@cef-ai/wallet 1.0.0 → 1.1.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.
- package/README.md +99 -4
- package/dist/index.cjs +243 -20
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +180 -53
- package/dist/index.d.ts +180 -53
- package/dist/index.js +243 -21
- package/dist/index.js.map +1 -1
- package/package.json +3 -3
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/transport/origin.ts","../src/transport/PopupTransport.ts","../src/EmbedWallet.ts","../src/protocol.ts","../src/transport/PopupHostBridge.ts","../src/transport/BroadcastSessionShare.ts"],"names":["data","pending","WalletError"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAUO,IAAM,sBAAA,GAA4C,CAAC,QAAA,EAAU,OAAO;AAMpE,SAAS,gBAAA,CAAiB,GAAuB,CAAA,EAAgC;AACtF,EAAA,IAAI,CAAC,CAAA,IAAK,CAAC,CAAA,EAAG,OAAO,KAAA;AACrB,EAAA,IAAI;AACF,IAAA,MAAM,EAAA,GAAK,IAAI,GAAA,CAAI,CAAC,CAAA;AACpB,IAAA,MAAM,EAAA,GAAK,IAAI,GAAA,CAAI,CAAC,CAAA;AACpB,IAAA,OAAO,EAAA,CAAG,WAAW,EAAA,CAAG,MAAA;AAAA,EAC1B,CAAA,CAAA,OAAQ,CAAA,EAAA;AACN,IAAA,OAAO,KAAA;AAAA,EACT;AACF;;;ACFA,IAAM,gBAAA,GAAmB,mDAAA;AAgBlB,IAAM,iBAAN,MAAqB;AAAA,EAQ1B,YAAY,OAAA,EAAgC;AAN5C,IAAA,IAAA,CAAQ,KAAA,GAA4B,IAAA;AACpC,IAAA,IAAA,CAAQ,OAAA,uBAA2C,GAAA,EAAI;AACvD,IAAA,IAAA,CAAQ,QAAA,GAAmD,IAAA;AAC3D,IAAA,IAAA,CAAQ,UAAA,GAAa,KAAA;AACrB,IAAA,IAAA,CAAQ,SAAwB,EAAC;AAG/B,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA,CAAA;AAAA,MACV,SAAA,EAAW,aAAA;AAAA,MACX,YAAa,UAAA,CAAmB,MAAA;AAAA,MAChC,gBAAA,EAAkB;AAAA,KAAA,EACf,OAAA,CAAA;AAAA,EAEP;AAAA,EAEM,OAAA,CACJ,IACA,EAAA,EAEY;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,SAAA,EAAA,WAHZ,OAAA,EACA,aAAA,EACA,IAAA,GAA+B,EAAC,EACpB;AA5DhB,MAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA6DI,MAAA,IAAI,CAAC,IAAA,CAAK,KAAA,IAAS,IAAA,CAAK,MAAM,MAAA,EAAQ;AACpC,QAAA,MAAM,UAAA,GAAA,CAAc,EAAA,GAAA,CAAA,EAAA,GAAA,UAAA,CAAmB,QAAA,KAAnB,IAAA,GAAA,MAAA,GAAA,EAAA,CAA6B,WAA7B,IAAA,GAAA,EAAA,GAAuC,EAAA;AAC3D,QAAA,MAAM,GAAA,GAAM,GAAG,IAAA,CAAK,IAAA,CAAK,YAAY,CAAA,qBAAA,EAAwB,kBAAA,CAAmB,UAAU,CAAC,CAAA,CAAA;AAC3F,QAAA,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,IAAA,CAAK,SAAA,CAAU,KAAK,gBAAgB,CAAA;AACtD,QAAA,IAAI,CAAC,KAAK,KAAA,EAAO;AACf,UAAA,MAAM,IAAI,WAAA,CAAY,eAAA,EAAiB,6BAA6B,CAAA;AAAA,QACtE;AAIA,QAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAClB,QAAA,IAAA,CAAK,SAAS,EAAC;AACf,QAAA,IAAA,CAAK,eAAA,EAAgB;AAAA,MACvB;AAEA,MAAA,MAAM,KAAK,OAAA,CAAQ,EAAA;AACnB,MAAA,MAAM,SAAA,GAAA,CAAY,EAAA,GAAA,IAAA,CAAK,SAAA,KAAL,IAAA,GAAA,EAAA,GAAkB,KAAK,IAAA,CAAK,gBAAA;AAE9C,MAAA,OAAO,IAAI,OAAA,CAAW,CAAC,OAAA,EAAS,MAAA,KAAW;AACzC,QAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,UAAA,IAAI,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,EAAE,CAAA,EAAG;AACxB,YAAA,IAAA,CAAK,OAAA,CAAQ,OAAO,EAAE,CAAA;AAEtB,YAAA,IAAA,CAAK,MAAA,GAAS,KAAK,MAAA,CAAO,MAAA,CAAO,CAAC,CAAA,KAAM,CAAA,CAAE,OAAO,EAAE,CAAA;AACnD,YAAA,MAAA,CAAO,IAAI,WAAA,CAAY,UAAA,EAAY,CAAA,SAAA,EAAY,OAAA,CAAQ,IAAI,CAAA,MAAA,EAAS,EAAE,CAAA,kBAAA,EAAqB,SAAS,CAAA,EAAA,CAAI,CAAC,CAAA;AAAA,UAC3G;AAAA,QACF,GAAG,SAAS,CAAA;AAEZ,QAAA,IAAA,CAAK,OAAA,CAAQ,IAAI,EAAA,EAAI;AAAA,UACnB,aAAA;AAAA,UACA,OAAA,EAAS,CAAC,GAAA,KAAQ,OAAA,CAAQ,GAAQ,CAAA;AAAA,UAClC,MAAA;AAAA,UACA;AAAA,SACD,CAAA;AAED,QAAA,IAAI,KAAK,UAAA,EAAY;AACnB,UAAA,IAAA,CAAK,KAAA,CAAO,WAAA,CAAY,OAAA,EAAS,IAAA,CAAK,KAAK,YAAY,CAAA;AAAA,QACzD,CAAA,MAAO;AAEL,UAAA,IAAA,CAAK,MAAA,CAAO,KAAK,OAAO,CAAA;AAAA,QAC1B;AAAA,MACF,CAAC,CAAA;AAAA,IACH,CAAA,CAAA;AAAA,EAAA;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAI,IAAA,CAAK,KAAA,IAAS,CAAC,IAAA,CAAK,MAAM,MAAA,EAAQ;AACpC,MAAA,IAAA,CAAK,MAAM,KAAA,EAAM;AAAA,IACnB;AACA,IAAA,IAAA,CAAK,KAAA,GAAQ,IAAA;AACb,IAAA,IAAA,CAAK,UAAA,GAAa,KAAA;AAClB,IAAA,IAAA,CAAK,SAAS,EAAC;AAAA,EACjB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,KAAA,EAAM;AACX,IAAA,IAAI,KAAK,QAAA,EAAU;AACjB,MAAA,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,mBAAA,CAAoB,SAAA,EAAW,KAAK,QAAQ,CAAA;AACjE,MAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,IAClB;AAAA,EACF;AAAA;AAAA,EAIQ,eAAA,GAAwB;AAC9B,IAAA,IAAI,KAAK,QAAA,EAAU;AACnB,IAAA,IAAA,CAAK,QAAA,GAAW,CAAC,KAAA,KAAwB,IAAA,CAAK,UAAU,KAAK,CAAA;AAC7D,IAAA,IAAA,CAAK,IAAA,CAAK,UAAA,CAAW,gBAAA,CAAiB,SAAA,EAAW,KAAK,QAAQ,CAAA;AAAA,EAChE;AAAA,EAEQ,UAAU,KAAA,EAA2B;AAC3C,IAAA,IAAI,CAAC,gBAAA,CAAiB,KAAA,CAAM,QAAQ,IAAA,CAAK,IAAA,CAAK,YAAY,CAAA,EAAG;AAI3D,MAAA,MAAMA,QAAO,KAAA,CAAM,IAAA;AACnB,MAAA,IAAIA,KAAAA,IAAQ,OAAOA,KAAAA,CAAK,EAAA,KAAO,QAAA,IAAY,KAAK,OAAA,CAAQ,GAAA,CAAIA,KAAAA,CAAK,EAAE,CAAA,EAAG;AACpE,QAAA,MAAMC,QAAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAID,MAAK,EAAE,CAAA;AACxC,QAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAOA,KAAAA,CAAK,EAAE,CAAA;AAC3B,QAAA,YAAA,CAAaC,SAAQ,KAAK,CAAA;AAC1B,QAAAA,QAAAA,CAAQ,MAAA;AAAA,UACN,IAAI,WAAA;AAAA,YACF,iBAAA;AAAA,YACA,iBAAiB,KAAA,CAAM,MAAM,CAAA,sBAAA,EAAyB,IAAA,CAAK,KAAK,YAAY,CAAA,EAAA;AAAA;AAC9E,SACF;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AACnB,IAAA,IAAI,CAAC,QAAQ,OAAO,IAAA,CAAK,SAAS,QAAA,IAAY,OAAO,IAAA,CAAK,EAAA,KAAO,QAAA,EAAU;AAI3E,IAAA,IAAI,IAAA,CAAK,SAAS,cAAA,EAAgB;AAChC,MAAA,IAAI,KAAK,UAAA,EAAY;AACrB,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,MAAA,MAAM,UAAU,IAAA,CAAK,MAAA;AACrB,MAAA,IAAA,CAAK,SAAS,EAAC;AACf,MAAA,IAAI,IAAA,CAAK,KAAA,IAAS,CAAC,IAAA,CAAK,MAAM,MAAA,EAAQ;AACpC,QAAA,KAAA,MAAW,KAAK,OAAA,EAAS;AACvB,UAAA,IAAA,CAAK,KAAA,CAAM,WAAA,CAAY,CAAA,EAAG,IAAA,CAAK,KAAK,YAAY,CAAA;AAAA,QAClD;AAAA,MACF;AACA,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,OAAA,GAAU,IAAA,CAAK,OAAA,CAAQ,GAAA,CAAI,KAAK,EAAE,CAAA;AACxC,IAAA,IAAI,CAAC,OAAA,EAAS;AAEd,IAAA,YAAA,CAAa,QAAQ,KAAK,CAAA;AAC1B,IAAA,IAAA,CAAK,OAAA,CAAQ,MAAA,CAAO,IAAA,CAAK,EAAE,CAAA;AAE3B,IAAA,IAAI,IAAA,CAAK,SAAS,cAAA,EAAgB;AAChC,MAAA,OAAA,CAAQ,MAAA,CAAO,IAAI,WAAA,CAAY,IAAA,CAAK,MAAyB,IAAA,CAAK,OAAA,EAAS,IAAA,CAAK,OAAO,CAAC,CAAA;AACxF,MAAA;AAAA,IACF;AAEA,IAAA,IAAI,CAAC,OAAA,CAAQ,aAAA,CAAc,QAAA,CAAS,IAAA,CAAK,IAAI,CAAA,EAAG;AAC9C,MAAA,OAAA,CAAQ,MAAA;AAAA,QACN,IAAI,YAAY,UAAA,EAAY,CAAA,mCAAA,EAAsC,KAAK,IAAI,CAAA,UAAA,EAAa,IAAA,CAAK,EAAE,CAAA,CAAA,CAAG;AAAA,OACpG;AACA,MAAA;AAAA,IACF;AAEA,IAAA,OAAA,CAAQ,QAAQ,IAAI,CAAA;AAAA,EACtB;AACF;AAEA,SAAS,aAAA,CAAc,KAAa,QAAA,EAAuC;AACzE,EAAA,MAAM,IAAK,UAAA,CAAmB,MAAA;AAC9B,EAAA,MAAM,MAAA,GAAS,CAAA,IAAA,IAAA,GAAA,MAAA,GAAA,CAAA,CAAG,IAAA,CAAK,GAAA,EAAK,QAAA,EAAU,QAAA,CAAA;AACtC,EAAA,OAAO,MAAA;AACT;;;AC7KO,IAAM,cAAN,MAAkB;AAAA,EAWvB,YAAY,IAAA,EAA0B;AALtC,IAAA,IAAA,CAAQ,UAAA,GAA+B,IAAA;AACvC,IAAA,IAAA,CAAQ,aAAA,GAA+B,IAAA;AACvC,IAAA,IAAA,CAAQ,aAA0B,EAAC;AAtCrC,IAAA,IAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA,EAAA;AA6CI,IAAA,MAAM,iBAAA,GAAA,CAAoB,EAAA,GAAA,IAAA,CAAK,YAAA,KAAL,IAAA,GAAA,MAAA,GAAA,EAAA,CAAmB,SAAA;AAC7C,IAAA,IAAI,CAAC,iBAAA,IAAqB,CAAC,IAAA,CAAK,YAAA,EAAc;AAC5C,MAAA,MAAM,IAAI,MAAM,4EAA4E,CAAA;AAAA,IAC9F;AACA,IAAA,IAAA,CAAK,QAAQ,IAAA,CAAK,KAAA;AAClB,IAAA,IAAA,CAAK,YAAA,GAAA,CAAe,EAAA,GAAA,IAAA,CAAK,YAAA,KAAL,IAAA,GAAA,EAAA,GAAqB,EAAA;AACzC,IAAA,IAAA,CAAK,KAAA,GAAQ,EAAE,KAAA,EAAA,CAAO,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,UAAL,IAAA,GAAA,MAAA,GAAA,EAAA,CAAY,KAAA,KAAZ,IAAA,GAAA,EAAA,GAAqB,GAAA,EAAK,SAAQ,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,KAAA,KAAL,IAAA,GAAA,MAAA,GAAA,EAAA,CAAY,MAAA,KAAZ,YAAsB,GAAA,EAAI;AAClF,IAAA,IAAA,CAAK,OAAA,GAAA,CAAU,EAAA,GAAA,IAAA,CAAK,OAAA,KAAL,IAAA,GAAA,EAAA,GAAgB,EAAA;AAC/B,IAAA,IAAA,CAAK,SAAA,GACH,iBAAA,IAAA,IAAA,GAAA,iBAAA,GACA,IAAI,cAAA,CAAe;AAAA,MACjB,cAAc,IAAA,CAAK;AAAA,KACpB,CAAA;AAAA,EACL;AAAA,EAEA,IAAI,UAAA,GAAsB;AACxB,IAAA,OAAO,KAAK,UAAA,KAAe,IAAA;AAAA,EAC7B;AAAA,EACA,IAAI,SAAA,GAA8B;AAChC,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AAAA,EACA,IAAI,YAAA,GAA8B;AAChC,IAAA,OAAO,IAAA,CAAK,aAAA;AAAA,EACd;AAAA,EAEM,QAAA,GAA8D;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,SAAA,EAAA,WAArD,IAAA,GAA2B,EAAC,EAAyB;AAClE,MAAA,OAAO,IAAA,CAAK,kBAAA,CAAmB,UAAA,EAAY,IAAI,CAAA;AAAA,IACjD,CAAA,CAAA;AAAA,EAAA;AAAA,EAEM,KAAA,GAA8B;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA;AAClC,MAAA,OAAO,IAAA,CAAK,mBAAmB,OAAO,CAAA;AAAA,IACxC,CAAA,CAAA;AAAA,EAAA;AAAA,EAEM,MAAA,GAAwB;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA;AAC5B,MAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,QAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,QAAA;AAAA,MACF;AACA,MAAA,MAAM,EAAA,GAAK,OAAO,UAAA,EAAW;AAC7B,MAAA,IAAI;AACF,QAAA,MAAM,KAAK,SAAA,CAAU,OAAA,CAAyD,EAAE,IAAA,EAAM,eAAA,EAAiB,IAAG,EAAG;AAAA,UAC3G;AAAA,SACD,CAAA;AAAA,MACH,SAAS,IAAA,EAAM;AAAA,MAEf;AACA,MAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,MAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,MAAA,IAAA,CAAK,UAAU,KAAA,EAAM;AACrB,MAAA,IAAA,CAAK,IAAA,CAAK,QAAA,EAAU,EAAE,IAAA,EAAM,UAAU,CAAA;AAAA,IACxC,CAAA,CAAA;AAAA,EAAA;AAAA,EAMA,UAAU,IAAA,EAAgE;AACxE,IAAA,IAAA,CAAK,eAAe,WAAW,CAAA;AAC/B,IAAA,MAAM,IAAA,GAAqB,CAAO,KAAA,EAAO,OAAA,KAAY,OAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA;AACnD,MAAA,MAAM,EAAA,GAAK,OAAO,UAAA,EAAW;AAC7B,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA;AAAA,QAClC,EAAE,IAAA,EAAM,aAAA,EAAe,IAAI,KAAA,EAAO,OAAA,EAAS,aAAa,KAAA,EAAM;AAAA,QAC9D,CAAC,eAAe;AAAA,OAClB;AACA,MAAA,MAAM,MAAM,MAAA,CAAO,MAAA;AACnB,MAAA,IAAI,EAAE,eAAe,UAAA,CAAA,EAAa;AAChC,QAAA,MAAM,IAAIC,WAAAA,CAAY,UAAA,EAAY,CAAA,+CAAA,EAAkD,OAAO,GAAG,CAAA,CAAA,CAAG,CAAA;AAAA,MACnG;AACA,MAAA,OAAO,GAAA;AAAA,IACT,CAAA,CAAA;AACA,IAAA,MAAM,YAAY,IAAA,CAAK,UAAA;AACvB,IAAA,QAAQ,KAAK,KAAA;AAAO,MAClB,KAAK,KAAA;AACH,QAAA,OAAO,IAAI,YAAA,CAAa,EAAE,SAAS,SAAA,CAAU,GAAA,EAAK,MAAM,CAAA;AAAA,MAC1D,KAAK,MAAA;AACH,QAAA,OAAO,IAAI,cAAA,CAAe,EAAE,SAAS,SAAA,CAAU,IAAA,EAAM,MAAM,CAAA;AAAA,MAC7D,KAAK,QAAA;AACH,QAAA,OAAO,IAAI,YAAA,CAAa,EAAE,SAAS,SAAA,CAAU,MAAA,EAAQ,MAAM,CAAA;AAAA,MAC7D;AACE,QAAA,MAAM,IAAIA,YAAY,YAAA,EAAc,CAAA,0BAAA,EAA6B,OAAQ,IAAA,CAAa,KAAK,CAAC,CAAA,CAAA,CAAG,CAAA;AAAA;AACnG,EACF;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAWA,QAAA,GAAsB;AACpB,IAAA,IAAA,CAAK,eAAe,UAAU,CAAA;AAC9B,IAAA,MAAM,YAAY,IAAA,CAAK,UAAA;AACvB,IAAA,MAAM,IAAA,GAAO,CACX,OAAA,EACA,MAAA,EACA,aAAA,KACwB,OAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA;AAIxB,MAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,QAAA,MAAM,IAAIA,WAAAA,CAAY,cAAA,EAAgB,yCAAyC,CAAA;AAAA,MACjF;AACA,MAAA,MAAM,EAAA,GAAK,OAAO,UAAA,EAAW;AAC7B,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA;AAAA,QAClC,EAAE,IAAA,EAAM,aAAA,EAAe,EAAA,EAAI,KAAA,EAAO,QAAQ,OAAA,EAAS,WAAA,EAAa,MAAA,IAAA,IAAA,GAAA,MAAA,GAAU,KAAA,EAAO,aAAA,EAAc;AAAA,QAC/F,CAAC,eAAe;AAAA,OAClB;AACA,MAAA,MAAM,MAAM,MAAA,CAAO,MAAA;AACnB,MAAA,IAAI,EAAE,eAAe,UAAA,CAAA,EAAa;AAChC,QAAA,MAAM,IAAIA,WAAAA,CAAY,UAAA,EAAY,CAAA,+CAAA,EAAkD,OAAO,GAAG,CAAA,CAAA,CAAG,CAAA;AAAA,MACnG;AACA,MAAA,OAAO,GAAA;AAAA,IACT,CAAA,CAAA;AACA,IAAA,OAAO;AAAA,MACL,IAAA,EAAM,SAAA;AAAA,MACN,SAAS,SAAA,CAAU,IAAA;AAAA,MACnB,SAAA,EAAW,mBAAA,CAAoB,SAAA,CAAU,MAAM,CAAA;AAAA,MAC/C,SAAS,MAAS,OAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA;AAAG,QAAA,OAAA,IAAA,CAAK,UAAA;AAAA,MAAA,CAAA,CAAA;AAAA,MAC1B,IAAA,EAAM,CAAC,KAAA,EAAO,MAAA,EAAQ,SAAS,IAAA,CAAK,KAAA,EAAO,MAAA,EAAQ,IAAA,IAAA,IAAA,GAAA,MAAA,GAAA,IAAA,CAAM,aAAa;AAAA,KACxE;AAAA,EACF;AAAA,EAEM,kBAAkB,GAAA,EAAmD;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA;AACzE,MAAA,IAAA,CAAK,eAAe,mBAAmB,CAAA;AACvC,MAAA,MAAM,EAAA,GAAK,OAAO,UAAA,EAAW;AAC7B,MAAA,MAAM,KAAA,GAAQ;AAAA,QACZ,cAAc,GAAA,CAAI,YAAA;AAAA,QAClB,OAAO,GAAA,CAAI,KAAA;AAAA,QACX,aAAa,GAAA,CAAI,WAAA;AAAA,QACjB,aAAa,GAAA,CAAI;AAAA,OACnB;AACA,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA;AAAA,QAClC,EAAE,IAAA,EAAM,0BAAA,EAA4B,IAAI,KAAA,EAAO,GAAA,EAAK,IAAI,GAAA,EAAI;AAAA,QAC5D,CAAC,eAAe;AAAA,OAClB;AACA,MAAA,OAAO,MAAA,CAAO,MAAA;AAAA,IAChB,CAAA,CAAA;AAAA,EAAA;AAAA,EAEM,gBAAA,GAA+E;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,SAAA,EAAA,WAA9D,MAAA,GAA4B,EAAC,EAAiC;AACnF,MAAA,IAAA,CAAK,eAAe,kBAAkB,CAAA;AACtC,MAAA,MAAM,EAAA,GAAK,OAAO,UAAA,EAAW;AAC7B,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA;AAAA,QAClC,EAAE,IAAA,EAAM,yBAAA,EAA2B,EAAA,EAAI,KAAA,EAAO,OAAO,KAAA,EAAM;AAAA,QAC3D,CAAC,eAAe;AAAA,OAClB;AACA,MAAA,OAAO,MAAA,CAAO,MAAA;AAAA,IAChB,CAAA,CAAA;AAAA,EAAA;AAAA,EAEM,gBAAgB,IAAA,EAAmD;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA;AACvE,MAAA,IAAA,CAAK,eAAe,iBAAiB,CAAA;AACrC,MAAA,MAAM,EAAA,GAAK,OAAO,UAAA,EAAW;AAC7B,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,OAAA;AAAA,QAClC,EAAE,MAAM,wBAAA,EAA0B,EAAA,EAAI,aAAa,IAAA,CAAK,WAAA,EAAa,KAAA,EAAO,IAAA,CAAK,KAAA,EAAM;AAAA,QACvF,CAAC,eAAe;AAAA,OAClB;AACA,MAAA,OAAO,MAAA,CAAO,MAAA;AAAA,IAChB,CAAA,CAAA;AAAA,EAAA;AAAA,EAEA,EAAA,CAAkC,MAAS,QAAA,EAAwC;AA/MrF,IAAA,IAAA,EAAA;AAgNI,IAAA,MAAM,MAAM,IAAA,CAAK,UAAA;AACjB,IAAA,CAAA,CAAC,EAAA,GAAA,GAAA,CAAA,IAAA,CAAA,KAAA,IAAA,GAAA,EAAA,GAAA,GAAA,CAAA,IAAA,CAAA,mBAAc,IAAI,GAAA,EAAI,EAAG,IAAI,QAAQ,CAAA;AACtC,IAAA,OAAO,IAAA;AAAA,EACT;AAAA,EAEA,GAAA,CAAmC,MAAS,QAAA,EAAwC;AArNtF,IAAA,IAAA,EAAA;AAsNI,IAAA,MAAM,MAAM,IAAA,CAAK,UAAA;AACjB,IAAA,CAAA,EAAA,GAAA,GAAA,CAAI,IAAI,CAAA,KAAR,IAAA,GAAA,MAAA,GAAA,EAAA,CAAW,MAAA,CAAO,QAAA,CAAA;AAClB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,UAAA,GAAa,IAAA;AAClB,IAAA,IAAA,CAAK,aAAA,GAAgB,IAAA;AACrB,IAAA,IAAA,CAAK,aAAa,EAAC;AACnB,IAAA,IAAA,CAAK,UAAU,OAAA,EAAQ;AAAA,EACzB;AAAA;AAAA,EAIQ,UAAA,GAAyB;AAC/B,IAAA,MAAM,SAAS,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,EAAA;AACxE,IAAA,OAAO,EAAE,KAAA,EAAO,IAAA,CAAK,OAAO,IAAA,EAAM,IAAA,CAAK,SAAS,MAAA,EAAO;AAAA,EACzD;AAAA,EAEc,mBAAmB,EAAA,EAAmF;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,SAAA,EAAA,WAAnF,MAAA,EAA8B,IAAA,GAA2B,EAAC,EAAyB;AAClH,MAAA,MAAM,EAAA,GAAK,OAAO,UAAA,EAAW;AAC7B,MAAA,MAAM,YAAA,GAA4B;AAAA,QAChC,IAAA,EAAM,cAAA;AAAA,QACN,EAAA;AAAA,QACA,UAAA,EAAY,KAAK,UAAA,EAAW;AAAA,QAC5B,MAAA;AAAA,QACA,OAAO,IAAA,CAAK;AAAA,OACd;AACA,MAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,SAAA,CAAU,QAA2D,YAAA,EAAc;AAAA,QAC3G;AAAA,OACD,CAAA;AACD,MAAA,IAAA,CAAK,aAAa,MAAA,CAAO,SAAA;AACzB,MAAA,IAAA,CAAK,gBAAgB,MAAA,CAAO,YAAA;AAC5B,MAAA,IAAA,CAAK,IAAA,CAAK,SAAS,EAAE,IAAA,EAAM,SAAS,SAAA,EAAW,MAAA,CAAO,WAAW,CAAA;AACjE,MAAA,OAAO,EAAE,SAAA,EAAW,MAAA,CAAO,SAAA,EAAW,YAAA,EAAc,OAAO,YAAA,EAAa;AAAA,IAC1E,CAAA,CAAA;AAAA,EAAA;AAAA,EAEQ,IAAA,CAAoC,MAAS,EAAA,EAA6C;AAChG,IAAA,MAAM,GAAA,GAAM,IAAA,CAAK,UAAA,CAAW,IAAI,CAAA;AAChC,IAAA,IAAI,CAAC,GAAA,EAAK;AACV,IAAA,KAAA,MAAW,YAAY,GAAA,EAAK;AAC1B,MAAA,IAAI;AACF,QAAA,QAAA,CAAS,EAAE,CAAA;AAAA,MACb,CAAA,CAAA,OAAQ,CAAA,EAAA;AAAA,MAER;AAAA,IACF;AAAA,EACF;AAAA,EAEQ,eAAe,MAAA,EAAsB;AAC3C,IAAA,IAAI,CAAC,KAAK,UAAA,EAAY;AACpB,MAAA,MAAM,IAAIA,WAAAA,CAAY,cAAA,EAAgB,CAAA,EAAG,MAAM,CAAA,eAAA,CAAiB,CAAA;AAAA,IAClE;AAAA,EACF;AACF;;;ACnOO,IAAM,sBAAA,GAAyB;ACpB/B,IAAM,kBAAN,MAAsB;AAAA,EAK3B,YAAY,OAAA,EAAiC;AAH7C,IAAA,IAAA,CAAiB,WAAuB,EAAC;AACzC,IAAA,IAAA,CAAQ,QAAA,GAAmD,IAAA;AAGzD,IAAA,IAAA,CAAK,IAAA,GAAO,cAAA,CAAA;AAAA,MACV,aAAc,UAAA,CAAmB;AAAA,KAAA,EAC9B,OAAA,CAAA;AAAA,EAEP;AAAA;AAAA,EAGA,EAAA,CAAkC,MAAS,OAAA,EAAuE;AAChH,IAAA,IAAA,CAAK,QAAA,CAAS,IAAI,CAAA,GAAI,OAAA;AACtB,IAAA,OAAO,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOA,KAAK,OAAA,EAA4B;AAC/B,IAAA,MAAM,SAAe,UAAA,CAAmB,MAAA;AACxC,IAAA,IAAI,CAAC,MAAA,IAAU,OAAO,MAAA,CAAO,gBAAgB,UAAA,EAAY;AAEvD,MAAA;AAAA,IACF;AACA,IAAA,MAAA,CAAO,WAAA,CAAY,OAAA,EAAS,IAAA,CAAK,IAAA,CAAK,UAAU,CAAA;AAAA,EAClD;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASA,KAAA,CAAM,IAAA,GAA2C,EAAC,EAAS;AACzD,IAAA,IAAI,KAAK,QAAA,EAAU;AACnB,IAAA,IAAA,CAAK,QAAA,GAAW,CAAC,KAAA,KAAwB,IAAA,CAAK,UAAU,KAAK,CAAA;AAC7D,IAAA,IAAA,CAAK,IAAA,CAAK,WAAA,CAAY,gBAAA,CAAiB,SAAA,EAAW,KAAK,QAAQ,CAAA;AAC/D,IAAA,IAAI,KAAK,aAAA,EAAe;AACtB,MAAA,IAAA,CAAK,IAAA,CAAK,EAAE,IAAA,EAAM,cAAA,EAAgB,IAAI,IAAA,CAAK,aAAA,CAAc,IAAI,CAAA;AAAA,IAC/D;AAAA,EACF;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAI,CAAC,KAAK,QAAA,EAAU;AACpB,IAAA,IAAA,CAAK,IAAA,CAAK,WAAA,CAAY,mBAAA,CAAoB,SAAA,EAAW,KAAK,QAAQ,CAAA;AAClE,IAAA,IAAA,CAAK,QAAA,GAAW,IAAA;AAAA,EAClB;AAAA;AAAA,EAIc,UAAU,KAAA,EAAoC;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,IAAA,EAAA,aAAA;AAnF9D,MAAA,IAAA,EAAA;AAoFI,MAAA,IAAI,CAAC,gBAAA,CAAiB,KAAA,CAAM,QAAQ,IAAA,CAAK,IAAA,CAAK,UAAU,CAAA,EAAG;AAEzD,QAAA;AAAA,MACF;AACA,MAAA,MAAM,OAAO,KAAA,CAAM,IAAA;AACnB,MAAA,IAAI,CAAC,QAAQ,OAAO,IAAA,CAAK,SAAS,QAAA,IAAY,OAAO,IAAA,CAAK,EAAA,KAAO,QAAA,EAAU;AAE3E,MAAA,MAAM,OAAA,GAAW,IAAA,CAAK,QAAA,CAAiB,IAAA,CAAK,IAAI,CAAA;AAChD,MAAA,IAAI,CAAC,OAAA,EAAS;AAEZ,QAAA,IAAA,CAAK,IAAA,CAAK;AAAA,UACR,IAAA,EAAM,cAAA;AAAA,UACN,IAAI,IAAA,CAAK,EAAA;AAAA,UACT,IAAA,EAAM,UAAA;AAAA,UACN,OAAA,EAAS,CAAA,2BAAA,EAA8B,IAAA,CAAK,IAAI,CAAA,CAAA;AAAA,SACjD,CAAA;AACD,QAAA;AAAA,MACF;AAEA,MAAA,IAAI;AACF,QAAA,MAAM,QAAQ,IAAA,EAAM,EAAE,MAAA,EAAQ,KAAA,CAAM,QAAQ,CAAA;AAAA,MAC9C,SAAS,GAAA,EAAK;AACZ,QAAA,IAAI,eAAeA,WAAAA,EAAa;AAC9B,UAAA,IAAA,CAAK,IAAA,CAAK;AAAA,YACR,IAAA,EAAM,cAAA;AAAA,YACN,IAAI,IAAA,CAAK,EAAA;AAAA,YACT,MAAM,GAAA,CAAI,IAAA;AAAA,YACV,OAAA,EAAA,CAAS,EAAA,GAAA,GAAA,CAAI,MAAA,KAAJ,IAAA,GAAA,EAAA,GAAc,EAAA;AAAA,YACvB,SAAS,GAAA,CAAI;AAAA,WACd,CAAA;AAAA,QACH,CAAA,MAAO;AACL,UAAA,IAAA,CAAK,IAAA,CAAK;AAAA,YACR,IAAA,EAAM,cAAA;AAAA,YACN,IAAI,IAAA,CAAK,EAAA;AAAA,YACT,IAAA,EAAM,UAAA;AAAA,YACN,SAAS,GAAA,YAAe,KAAA,GAAQ,GAAA,CAAI,OAAA,GAAU,OAAO,GAAG;AAAA,WACzD,CAAA;AAAA,QACH;AAAA,MACF;AAAA,IACF,CAAA,CAAA;AAAA,EAAA;AACF;;;ACpGA,IAAM,0BAAA,GAA6B,GAAA;AAa5B,IAAM,wBAAN,MAA4B;AAAA,EAKjC,YAAY,IAAA,EAAoC;AAFhD,IAAA,IAAA,CAAQ,SAAA,GAAY,KAAA;AA8DpB,IAAA,IAAA,CAAQ,SAAA,GAAY,CAAC,EAAA,KAAoD;AAtG3E,MAAA,IAAA,EAAA,EAAA,EAAA;AAuGI,MAAA,MAAM,MAAM,EAAA,CAAG,IAAA;AACf,MAAA,IAAI,GAAA,CAAI,SAAS,iBAAA,EAAmB;AAClC,QAAA,MAAM,OAAA,GAAU,IAAA,CAAK,IAAA,CAAK,UAAA,EAAW;AACrC,QAAA,IAAI,CAAC,OAAA,IAAW,OAAA,CAAQ,KAAA,IAAS,IAAA,CAAK,KAAI,EAAG;AAC7C,QAAA,IAAA,CAAK,QAAQ,WAAA,CAAY;AAAA,UACvB,IAAA,EAAM,eAAA;AAAA,UACN,WAAW,GAAA,CAAI,SAAA;AAAA,UACf,QAAQ,OAAA,CAAQ,MAAA;AAAA,UAChB,SAAS,OAAA,CAAQ,OAAA;AAAA,UACjB,WAAW,OAAA,CAAQ,SAAA;AAAA,UACnB,OAAO,OAAA,CAAQ;AAAA,SACW,CAAA;AAC5B,QAAA;AAAA,MACF;AACA,MAAA,IAAI,GAAA,CAAI,SAAS,QAAA,EAAU;AACzB,QAAA,CAAA,EAAA,GAAA,CAAA,EAAA,GAAA,IAAA,CAAK,MAAK,QAAA,KAAV,IAAA,GAAA,MAAA,GAAA,EAAA,CAAA,IAAA,CAAA,EAAA,CAAA;AACA,QAAA;AAAA,MACF;AAAA,IACF,CAAA;AA9EE,IAAA,IAAA,CAAK,IAAA,GAAO,IAAA;AACZ,IAAA,IAAA,CAAK,OAAA,GAAU,IAAI,gBAAA,CAAiB,sBAAsB,CAAA;AAAA,EAC5D;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOM,OAAA,GAA6E;AAAA,IAAA,OAAA,OAAA,CAAA,IAAA,EAAA,SAAA,EAAA,WAArE,IAAA,GAA+B,EAAC,EAAqC;AApDrF,MAAA,IAAA,EAAA;AAqDI,MAAA,MAAM,SAAA,GAAY,OAAO,UAAA,EAAW;AACpC,MAAA,MAAM,SAAA,GAAA,CAAY,EAAA,GAAA,IAAA,CAAK,SAAA,KAAL,IAAA,GAAA,EAAA,GAAkB,0BAAA;AAEpC,MAAA,OAAO,IAAI,OAAA,CAAiC,CAAC,OAAA,KAAY;AACvD,QAAA,MAAM,KAAA,GAAQ,CAAC,EAAA,KAA8C;AAC3D,UAAA,IAAI,EAAA,CAAG,IAAA,CAAK,IAAA,KAAS,eAAA,IAAmB,EAAA,CAAG,IAAA,CAAK,SAAA,KAAc,SAAA,IAAa,EAAA,CAAG,IAAA,CAAK,KAAA,GAAQ,IAAA,CAAK,KAAI,EAAG;AACrG,YAAA,IAAA,CAAK,OAAA,CAAQ,mBAAA,CAAoB,SAAA,EAAW,KAAK,CAAA;AACjD,YAAA,YAAA,CAAa,KAAK,CAAA;AAClB,YAAA,OAAA,CAAQ;AAAA,cACN,MAAA,EAAQ,GAAG,IAAA,CAAK,MAAA;AAAA,cAChB,OAAA,EAAS,GAAG,IAAA,CAAK,OAAA;AAAA,cACjB,SAAA,EAAW,GAAG,IAAA,CAAK,SAAA;AAAA,cACnB,KAAA,EAAO,GAAG,IAAA,CAAK;AAAA,aAChB,CAAA;AAAA,UACH;AAAA,QACF,CAAA;AACA,QAAA,IAAA,CAAK,OAAA,CAAQ,gBAAA,CAAiB,SAAA,EAAW,KAAK,CAAA;AAC9C,QAAA,MAAM,KAAA,GAAQ,WAAW,MAAM;AAC7B,UAAA,IAAA,CAAK,OAAA,CAAQ,mBAAA,CAAoB,SAAA,EAAW,KAAK,CAAA;AACjD,UAAA,OAAA,CAAQ,IAAI,CAAA;AAAA,QACd,GAAG,SAAS,CAAA;AAEZ,QAAA,IAAA,CAAK,QAAQ,WAAA,CAAY,EAAE,IAAA,EAAM,iBAAA,EAAmB,WAAsC,CAAA;AAAA,MAC5F,CAAC,CAAA;AAAA,IACH,CAAA,CAAA;AAAA,EAAA;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAI,KAAK,SAAA,EAAW;AACpB,IAAA,IAAA,CAAK,SAAA,GAAY,IAAA;AACjB,IAAA,IAAA,CAAK,OAAA,CAAQ,gBAAA,CAAiB,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AAAA,EACzD;AAAA,EAEA,IAAA,GAAa;AACX,IAAA,IAAA,CAAK,OAAA,CAAQ,mBAAA,CAAoB,SAAA,EAAW,IAAA,CAAK,SAAS,CAAA;AAC1D,IAAA,IAAA,CAAK,SAAA,GAAY,KAAA;AAAA,EACnB;AAAA;AAAA,EAGA,eAAA,GAAwB;AACtB,IAAA,IAAA,CAAK,OAAA,CAAQ,WAAA,CAAY,EAAE,IAAA,EAAM,UAAqC,CAAA;AAAA,EACxE;AAAA;AAAA,EAGA,KAAA,GAAc;AACZ,IAAA,IAAA,CAAK,IAAA,EAAK;AACV,IAAA,IAAA,CAAK,QAAQ,KAAA,EAAM;AAAA,EACrB;AAsBF","file":"index.js","sourcesContent":["/**\n * Origin verification helpers used by both ends of the popup transport.\n * Spec §5.3.\n */\n\n/**\n * Schemes that we accept for origins. Production uses https only; we allow\n * http here so test setups and `localhost:port` work — callers can layer\n * tighter rules (e.g. \"only https in production\") on top.\n */\nexport const ALLOWED_ORIGIN_SCHEMES: readonly string[] = ['https:', 'http:'];\n\n/**\n * Strict origin equality check. Returns true iff both inputs are non-empty,\n * URL-parseable, and have matching `origin` (scheme + host + port).\n */\nexport function isMatchingOrigin(a: string | undefined, b: string | undefined): boolean {\n if (!a || !b) return false;\n try {\n const ua = new URL(a);\n const ub = new URL(b);\n return ua.origin === ub.origin;\n } catch {\n return false;\n }\n}\n","import { WalletError, type WalletErrorCode } from '@cef-ai/wallet-api-client';\nimport type { HostToPopup, PopupToHost } from '../protocol';\nimport { isMatchingOrigin } from './origin';\nimport type { PopupHandle, PopupOpener } from './types';\n\nexport interface PopupTransportOptions {\n /** Expected origin of the wallet popup, e.g. 'https://wallet.example.com'. */\n walletOrigin: string;\n /** Defaults to `(url, features) => window.open(url, '_blank', features)`. */\n openPopup?: PopupOpener;\n /** Window object hosting the event listener. Defaults to `globalThis.window`. */\n hostWindow?: Window;\n /** Default per-request timeout. Defaults to 60_000 ms. */\n defaultTimeoutMs?: number;\n}\n\ninterface PendingRequest {\n expectedTypes: PopupToHost['type'][];\n resolve: (msg: PopupToHost) => void;\n reject: (err: WalletError) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst DEFAULT_FEATURES = 'width=420,height=640,resizable=yes,scrollbars=yes';\n\n/**\n * Host-side popup transport. Spec §5.\n *\n * Use one `PopupTransport` instance per `EmbedWallet`. The instance owns a\n * single popup window at a time, opens it on demand, auto-reopens on the next\n * `request()` after it's been closed, and correlates each in-flight request\n * by its message `id`.\n *\n * Wire handshake: every freshly opened popup must send `wallet:ready` before\n * this transport will post any `HostToPopup` envelope. Without the handshake,\n * `postMessage` may fire before the popup document has executed its `message`\n * listener and the message is dropped. Outbound messages are queued in\n * `outbox` while `popupReady === false`; `wallet:ready` flushes them.\n */\nexport class PopupTransport {\n private readonly opts: Required<PopupTransportOptions>;\n private popup: PopupHandle | null = null;\n private pending: Map<string, PendingRequest> = new Map();\n private listener: ((event: MessageEvent) => void) | null = null;\n private popupReady = false;\n private outbox: HostToPopup[] = [];\n\n constructor(options: PopupTransportOptions) {\n this.opts = {\n openPopup: defaultOpener,\n hostWindow: (globalThis as any).window,\n defaultTimeoutMs: 60_000,\n ...options,\n };\n }\n\n async request<T extends PopupToHost>(\n message: HostToPopup,\n expectedTypes: T['type'][],\n init: { timeoutMs?: number } = {},\n ): Promise<T> {\n if (!this.popup || this.popup.closed) {\n const hostOrigin = (globalThis as any).location?.origin ?? '';\n const url = `${this.opts.walletOrigin}/embed/wallet?origin=${encodeURIComponent(hostOrigin)}`;\n this.popup = this.opts.openPopup(url, DEFAULT_FEATURES);\n if (!this.popup) {\n throw new WalletError('popup-blocked', 'popup window failed to open');\n }\n // Fresh popup: reset handshake state. Any in-flight outbox from a prior\n // popup session is dropped; those requests have their own timers and\n // will fail through the normal timeout path.\n this.popupReady = false;\n this.outbox = [];\n this.ensureListening();\n }\n\n const id = message.id;\n const timeoutMs = init.timeoutMs ?? this.opts.defaultTimeoutMs;\n\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (this.pending.has(id)) {\n this.pending.delete(id);\n // Also drop from the outbox if it never got flushed.\n this.outbox = this.outbox.filter((m) => m.id !== id);\n reject(new WalletError('internal', `request \"${message.type}\" (id=${id}) timed out after ${timeoutMs}ms`));\n }\n }, timeoutMs);\n\n this.pending.set(id, {\n expectedTypes,\n resolve: (msg) => resolve(msg as T),\n reject,\n timer,\n });\n\n if (this.popupReady) {\n this.popup!.postMessage(message, this.opts.walletOrigin);\n } else {\n // Queue until the popup announces `wallet:ready`.\n this.outbox.push(message);\n }\n });\n }\n\n /** Close the popup if open. Pending requests will time out normally. */\n close(): void {\n if (this.popup && !this.popup.closed) {\n this.popup.close();\n }\n this.popup = null;\n this.popupReady = false;\n this.outbox = [];\n }\n\n /**\n * Tear down the transport entirely. Closes the popup AND removes the host-\n * window message listener. After `destroy()`, the transport instance cannot\n * be reused — callers should drop the reference.\n *\n * Use `close()` if you only want to close the popup but keep the transport\n * alive for a later re-open.\n */\n destroy(): void {\n this.close();\n if (this.listener) {\n this.opts.hostWindow.removeEventListener('message', this.listener);\n this.listener = null;\n }\n }\n\n // ---- internal -------------------------------------------------------------\n\n private ensureListening(): void {\n if (this.listener) return;\n this.listener = (event: MessageEvent) => this.onMessage(event);\n this.opts.hostWindow.addEventListener('message', this.listener);\n }\n\n private onMessage(event: MessageEvent): void {\n if (!isMatchingOrigin(event.origin, this.opts.walletOrigin)) {\n // Origin-mismatched messages might still target a pending request id —\n // we reject that pending request explicitly so callers get a clear signal\n // rather than waiting for a timeout.\n const data = event.data as PopupToHost | undefined;\n if (data && typeof data.id === 'string' && this.pending.has(data.id)) {\n const pending = this.pending.get(data.id)!;\n this.pending.delete(data.id);\n clearTimeout(pending.timer);\n pending.reject(\n new WalletError(\n 'origin-mismatch',\n `message from \"${event.origin}\" rejected (expected \"${this.opts.walletOrigin}\")`,\n ),\n );\n }\n return;\n }\n\n const data = event.data as PopupToHost | undefined;\n if (!data || typeof data.type !== 'string' || typeof data.id !== 'string') return;\n\n // Handshake: a freshly loaded popup announces itself with `wallet:ready`.\n // Flush any messages that were queued before the popup's listener was wired.\n if (data.type === 'wallet:ready') {\n if (this.popupReady) return;\n this.popupReady = true;\n const toFlush = this.outbox;\n this.outbox = [];\n if (this.popup && !this.popup.closed) {\n for (const m of toFlush) {\n this.popup.postMessage(m, this.opts.walletOrigin);\n }\n }\n return;\n }\n\n const pending = this.pending.get(data.id);\n if (!pending) return;\n\n clearTimeout(pending.timer);\n this.pending.delete(data.id);\n\n if (data.type === 'wallet:error') {\n pending.reject(new WalletError(data.code as WalletErrorCode, data.message, data.traceId));\n return;\n }\n\n if (!pending.expectedTypes.includes(data.type)) {\n pending.reject(\n new WalletError('internal', `received unexpected response type \"${data.type}\" for id \"${data.id}\"`),\n );\n return;\n }\n\n pending.resolve(data);\n }\n}\n\nfunction defaultOpener(url: string, features?: string): PopupHandle | null {\n const w = (globalThis as any).window;\n const opened = w?.open(url, '_blank', features);\n return opened as PopupHandle | null;\n}\n","import { WalletError } from '@cef-ai/wallet-api-client';\nimport type { Addresses } from '@cef-ai/wallet-identity';\nimport { decodeEd25519Pubkey } from '@cef-ai/wallet-identity';\nimport { EthersSigner, PolkadotSigner, SolanaSigner, type InternalSign } from '@cef-ai/wallet-signers';\nimport type { CefSigner, SignIntent } from './signer';\nimport type {\n EmbedWalletOptions,\n LoginResult,\n DelegationRequest,\n DelegationResult,\n SignerSpec,\n WalletEvent,\n WalletEventListener,\n ApplicationFilter,\n ApplicationBody,\n ApplicationRecord,\n} from './types';\nimport type { AppContext, HostToPopup, PopupToHost } from './protocol';\nimport { PopupTransport } from './transport/PopupTransport';\n\ntype ListenerMap = { [T in WalletEvent['type']]?: Set<WalletEventListener<T>> };\n\n/**\n * Public SDK class. v2.0.0. Spec §4.\n *\n * Drives the popup transport: every method that does meaningful work opens\n * (or reuses) a popup at `walletOrigin/embed/*`, sends a `HostToPopup`\n * message, awaits the matching `PopupToHost` response, and updates local\n * state. See spec §5 for the wire protocol.\n */\nexport class EmbedWallet {\n readonly appId: string;\n readonly walletOrigin: string;\n readonly popup: { width: number; height: number };\n readonly appName: string;\n\n private _addresses: Addresses | null = null;\n private _credentialId: string | null = null;\n private _listeners: ListenerMap = {};\n private readonly transport: PopupTransport;\n\n constructor(opts: EmbedWalletOptions) {\n // `walletOrigin` is required for real use — the SDK builds a PopupTransport\n // pinned to it. The `__internal__.transport` test seam supplies its own\n // origin-pinned transport, so walletOrigin may be omitted in that case.\n const injectedTransport = opts.__internal__?.transport;\n if (!injectedTransport && !opts.walletOrigin) {\n throw new Error('EmbedWallet: `walletOrigin` is required (e.g. https://wallet.example.com).');\n }\n this.appId = opts.appId;\n this.walletOrigin = opts.walletOrigin ?? '';\n this.popup = { width: opts.popup?.width ?? 420, height: opts.popup?.height ?? 640 };\n this.appName = opts.appName ?? '';\n this.transport =\n injectedTransport ??\n new PopupTransport({\n walletOrigin: this.walletOrigin,\n });\n }\n\n get isLoggedIn(): boolean {\n return this._addresses !== null;\n }\n get addresses(): Addresses | null {\n return this._addresses;\n }\n get credentialId(): string | null {\n return this._credentialId;\n }\n\n async register(opts: { label?: string } = {}): Promise<LoginResult> {\n return this.helloAndAwaitLogin('register', opts);\n }\n\n async login(): Promise<LoginResult> {\n return this.helloAndAwaitLogin('login');\n }\n\n async logout(): Promise<void> {\n if (!this._addresses) {\n this.transport.close();\n return;\n }\n const id = crypto.randomUUID();\n try {\n await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>({ type: 'wallet:logout', id }, [\n 'wallet:result',\n ]);\n } catch (_err) {\n // Ignore — local state still gets cleared below.\n }\n this._addresses = null;\n this._credentialId = null;\n this.transport.close();\n this.emit('logout', { type: 'logout' });\n }\n\n getSigner(spec: { chain: 'evm' }): EthersSigner;\n getSigner(spec: { chain: 'cere' }): PolkadotSigner;\n getSigner(spec: { chain: 'solana' }): SolanaSigner;\n getSigner(spec: SignerSpec): EthersSigner | PolkadotSigner | SolanaSigner;\n getSigner(spec: SignerSpec): EthersSigner | PolkadotSigner | SolanaSigner {\n this.assertLoggedIn('getSigner');\n const sign: InternalSign = async (chain, payload) => {\n const id = crypto.randomUUID();\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:sign', id, chain, payload, requestKind: 'sdk' },\n ['wallet:result'],\n );\n const sig = result.result;\n if (!(sig instanceof Uint8Array)) {\n throw new WalletError('internal', `popup returned non-Uint8Array sign result (got ${typeof sig})`);\n }\n return sig;\n };\n const addresses = this._addresses!;\n switch (spec.chain) {\n case 'evm':\n return new EthersSigner({ address: addresses.evm, sign });\n case 'cere':\n return new PolkadotSigner({ address: addresses.cere, sign });\n case 'solana':\n return new SolanaSigner({ address: addresses.solana, sign });\n default:\n throw new WalletError('validation', `getSigner: unknown chain \"${String((spec as any).chain)}\"`);\n }\n }\n\n /**\n * Expose the wallet as a chain-free `@cef-ai/signer` over the Cere\n * Ed25519 key — the pluggable-signer seam `@cef-ai/account` consumes for DDC\n * and `@cef-ai/chain` adapts for extrinsics.\n *\n * `publicKey` is recovered from the (public) Solana address — no key material\n * leaves the popup's `SessionVault`. `sign(bytes, 'extrinsic', { humanReadable })`\n * routes through the popup's extrinsic-consent screen.\n */\n asSigner(): CefSigner {\n this.assertLoggedIn('asSigner');\n const addresses = this._addresses!;\n const send = async (\n payload: Uint8Array,\n intent: SignIntent | undefined,\n humanReadable: string | undefined,\n ): Promise<Uint8Array> => {\n // `asSigner()` captured the addresses at call time; if the user has since\n // logged out (e.g. cross-tab logout), fail fast here rather than sending a\n // `wallet:sign` the popup would reject with `unauthorized`.\n if (!this.isLoggedIn) {\n throw new WalletError('unauthorized', 'asSigner: wallet is no longer logged in');\n }\n const id = crypto.randomUUID();\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:sign', id, chain: 'cere', payload, requestKind: intent ?? 'sdk', humanReadable },\n ['wallet:result'],\n );\n const sig = result.result;\n if (!(sig instanceof Uint8Array)) {\n throw new WalletError('internal', `popup returned non-Uint8Array sign result (got ${typeof sig})`);\n }\n return sig;\n };\n return {\n type: 'ed25519',\n address: addresses.cere,\n publicKey: decodeEd25519Pubkey(addresses.solana),\n isReady: async () => this.isLoggedIn,\n sign: (bytes, intent, opts) => send(bytes, intent, opts?.humanReadable),\n };\n }\n\n async requestDelegation(req: DelegationRequest): Promise<DelegationResult> {\n this.assertLoggedIn('requestDelegation');\n const id = crypto.randomUUID();\n const scope = {\n capabilities: req.capabilities,\n appId: req.appId,\n agentPubkey: req.agentPubkey,\n constraints: req.constraints,\n };\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:requestDelegation', id, scope, ttl: req.ttl },\n ['wallet:result'],\n );\n return result.result as DelegationResult;\n }\n\n async findApplications(filter: ApplicationFilter = {}): Promise<ApplicationRecord[]> {\n this.assertLoggedIn('findApplications');\n const id = crypto.randomUUID();\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:findApplications', id, appId: filter.appId },\n ['wallet:result'],\n );\n return result.result as ApplicationRecord[];\n }\n\n async saveApplication(body: ApplicationBody): Promise<ApplicationRecord> {\n this.assertLoggedIn('saveApplication');\n const id = crypto.randomUUID();\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:saveApplication', id, permissions: body.permissions, email: body.email },\n ['wallet:result'],\n );\n return result.result as ApplicationRecord;\n }\n\n on<T extends WalletEvent['type']>(type: T, listener: WalletEventListener<T>): this {\n const map = this._listeners as Record<string, Set<WalletEventListener<any>>>;\n (map[type] ??= new Set()).add(listener);\n return this;\n }\n\n off<T extends WalletEvent['type']>(type: T, listener: WalletEventListener<T>): this {\n const map = this._listeners as Record<string, Set<WalletEventListener<any>>>;\n map[type]?.delete(listener);\n return this;\n }\n\n /**\n * Tear down the wallet instance. Closes any open popup, removes transport\n * listeners, clears in-memory state. Call from your app's unmount hook.\n *\n * After dispose(), this instance is not reusable — construct a new one.\n */\n dispose(): void {\n this._addresses = null;\n this._credentialId = null;\n this._listeners = {};\n this.transport.destroy();\n }\n\n // ---- private --------------------------------------------------------------\n\n private appContext(): AppContext {\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n return { appId: this.appId, name: this.appName, origin };\n }\n\n private async helloAndAwaitLogin(intent: 'register' | 'login', opts: { label?: string } = {}): Promise<LoginResult> {\n const id = crypto.randomUUID();\n const helloMessage: HostToPopup = {\n type: 'wallet:hello',\n id,\n appContext: this.appContext(),\n intent,\n label: opts.label,\n };\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:login:ok' }>>(helloMessage, [\n 'wallet:login:ok',\n ]);\n this._addresses = result.addresses;\n this._credentialId = result.credentialId;\n this.emit('login', { type: 'login', addresses: result.addresses });\n return { addresses: result.addresses, credentialId: result.credentialId };\n }\n\n private emit<T extends WalletEvent['type']>(type: T, ev: Extract<WalletEvent, { type: T }>): void {\n const set = this._listeners[type] as Set<WalletEventListener<T>> | undefined;\n if (!set) return;\n for (const listener of set) {\n try {\n listener(ev);\n } catch {\n // Listener errors are isolated.\n }\n }\n }\n\n private assertLoggedIn(method: string): void {\n if (!this._addresses) {\n throw new WalletError('unauthorized', `${method}: not logged in`);\n }\n }\n}\n","import type { Addresses, Chain } from '@cef-ai/wallet-identity';\nimport type { WalletErrorCode } from '@cef-ai/wallet-api-client';\nimport type { ApplicationBody, ApplicationFilter, DelegationScope } from './types';\n\nexport interface AppContext {\n appId: string;\n name: string;\n origin: string;\n}\n\n/** Spec §5.2. Messages sent from a host page to a wallet popup. */\nexport type HostToPopup =\n | { type: 'wallet:hello'; id: string; appContext: AppContext; intent: 'register' | 'login'; label?: string }\n | { type: 'wallet:requestDelegation'; id: string; scope: DelegationScope; ttl: string }\n | { type: 'wallet:sign'; id: string; chain: Chain; payload: Uint8Array; requestKind: string; humanReadable?: string }\n | ({ type: 'wallet:saveApplication'; id: string } & ApplicationBody)\n | ({ type: 'wallet:findApplications'; id: string } & ApplicationFilter)\n | { type: 'wallet:logout'; id: string };\n\n/**\n * Spec §5.2. Messages sent from a wallet popup back to the host.\n *\n * On `wallet:error`, `message` carries the human-readable detail\n * (what `WalletError.detail` returns), NOT the compound `Error.message`\n * (`\"${code}: ${detail}\"`). The compound is reconstructable from `code + message`\n * on the receiving side. Serialisers in the popup MUST send `err.detail ?? ''`,\n * not `err.message`.\n */\nexport type PopupToHost =\n | { type: 'wallet:ready'; id: string }\n | { type: 'wallet:login:ok'; id: string; addresses: Addresses; credentialId: string }\n | { type: 'wallet:result'; id: string; result: unknown }\n | { type: 'wallet:error'; id: string; code: WalletErrorCode; message: string; traceId?: string };\n\n/** Spec §5.5. Channel name: `scp-wallet-v2`. Wallet-origin tabs only. */\nexport type BroadcastChannelMessage =\n | { type: 'request-session'; requestId: string }\n | {\n type: 'offer-session';\n requestId: string;\n edSeed: Uint8Array;\n secpKey: Uint8Array;\n addresses: Addresses;\n /** absolute Unix epoch ms when session keys expire */ expMs: number;\n }\n | { type: 'logout' };\n\nexport const BROADCAST_CHANNEL_NAME = 'scp-wallet-v2';\n","import { WalletError } from '@cef-ai/wallet-api-client';\nimport type { HostToPopup, PopupToHost } from '../protocol';\nimport { isMatchingOrigin } from './origin';\nimport type { PopupMessageHandler } from './types';\n\nexport interface PopupHostBridgeOptions {\n /** Expected origin of the host page (the page that opened this popup). */\n hostOrigin: string;\n /** The window this bridge runs in. Defaults to `globalThis`. */\n popupWindow?: Window;\n}\n\ntype HandlerMap = {\n [T in HostToPopup['type']]?: PopupMessageHandler<Extract<HostToPopup, { type: T }>>;\n};\n\n/**\n * Popup-side bridge. Spec §5.\n *\n * The wallet SPA constructs one of these at boot, registers handlers via\n * `on(type, fn)`, and calls `start()` to begin listening. Each inbound\n * `HostToPopup` message that matches a registered handler is dispatched;\n * the handler is responsible for calling `bridge.send(...)` to reply.\n *\n * Handlers may throw `WalletError`; the bridge automatically converts the\n * throw into a `wallet:error` response keyed by the inbound message id.\n */\nexport class PopupHostBridge {\n private readonly opts: Required<PopupHostBridgeOptions>;\n private readonly handlers: HandlerMap = {};\n private listener: ((event: MessageEvent) => void) | null = null;\n\n constructor(options: PopupHostBridgeOptions) {\n this.opts = {\n popupWindow: (globalThis as any).window,\n ...options,\n };\n }\n\n /** Register a handler for a specific message type. Replaces any prior handler. */\n on<T extends HostToPopup['type']>(type: T, handler: PopupMessageHandler<Extract<HostToPopup, { type: T }>>): this {\n this.handlers[type] = handler as any;\n return this;\n }\n\n /**\n * Send a `PopupToHost` message back to the opener. The bridge does not\n * remember the host-window reference itself — it reads `globalThis.opener`\n * each call, so it survives popup re-opens.\n */\n send(message: PopupToHost): void {\n const opener: any = (globalThis as any).opener;\n if (!opener || typeof opener.postMessage !== 'function') {\n // No opener — popup was opened standalone or the opener is closed.\n return;\n }\n opener.postMessage(message, this.opts.hostOrigin);\n }\n\n /**\n * Start listening for inbound messages.\n *\n * If `announceReady` is provided, sends a `wallet:ready` message immediately.\n * Use this when the popup wants to signal \"I'm here\" without waiting for the\n * host's first call.\n */\n start(opts: { announceReady?: { id: string } } = {}): void {\n if (this.listener) return;\n this.listener = (event: MessageEvent) => this.onMessage(event);\n this.opts.popupWindow.addEventListener('message', this.listener);\n if (opts.announceReady) {\n this.send({ type: 'wallet:ready', id: opts.announceReady.id });\n }\n }\n\n stop(): void {\n if (!this.listener) return;\n this.opts.popupWindow.removeEventListener('message', this.listener);\n this.listener = null;\n }\n\n // ---- internal -------------------------------------------------------------\n\n private async onMessage(event: MessageEvent): Promise<void> {\n if (!isMatchingOrigin(event.origin, this.opts.hostOrigin)) {\n // Silently drop.\n return;\n }\n const data = event.data as HostToPopup | undefined;\n if (!data || typeof data.type !== 'string' || typeof data.id !== 'string') return;\n\n const handler = (this.handlers as any)[data.type] as PopupMessageHandler<HostToPopup> | undefined;\n if (!handler) {\n // No handler registered — reply with a typed error.\n this.send({\n type: 'wallet:error',\n id: data.id,\n code: 'internal',\n message: `no handler registered for \"${data.type}\"`,\n });\n return;\n }\n\n try {\n await handler(data, { origin: event.origin });\n } catch (err) {\n if (err instanceof WalletError) {\n this.send({\n type: 'wallet:error',\n id: data.id,\n code: err.code,\n message: err.detail ?? '',\n traceId: err.traceId,\n });\n } else {\n this.send({\n type: 'wallet:error',\n id: data.id,\n code: 'internal',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n}\n","import { BROADCAST_CHANNEL_NAME, type BroadcastChannelMessage } from '../protocol';\nimport type { Addresses } from '@cef-ai/wallet-identity';\n\nexport interface BroadcastSession {\n edSeed: Uint8Array;\n secpKey: Uint8Array;\n addresses: Addresses;\n /** Absolute Unix epoch ms when the session expires. */\n expMs: number;\n}\n\nexport interface BroadcastSessionShareOptions {\n /**\n * Returns the local session if this tab has one to offer. Called whenever\n * another tab broadcasts `request-session`.\n */\n getSession: () => BroadcastSession | null;\n /**\n * Called when another tab broadcasts a `logout` message. The local handler\n * should wipe its own session.\n */\n onLogout?: () => void;\n}\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 200;\n\n/**\n * Popup-side cross-tab session sharing. Spec §5.5.\n *\n * - `request()`: broadcast `request-session`, wait up to 200ms for an offer.\n * - `start()`: listen for incoming requests; reply with `offer-session` if we\n * have a non-expired session and `getSession()` returns it.\n * - `broadcastLogout()`: notify peers to wipe their sessions too.\n *\n * Channel name is the spec-locked `scp-wallet-v2`. Only wallet-origin popups\n * join. Host pages do not participate.\n */\nexport class BroadcastSessionShare {\n private readonly channel: BroadcastChannel;\n private readonly opts: BroadcastSessionShareOptions;\n private listening = false;\n\n constructor(opts: BroadcastSessionShareOptions) {\n this.opts = opts;\n this.channel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);\n }\n\n /**\n * Broadcast a `request-session` and wait for an `offer-session` from another\n * tab. Resolves with the offered session, or null if nobody offered before\n * the timeout.\n */\n async request(opts: { timeoutMs?: number } = {}): Promise<BroadcastSession | null> {\n const requestId = crypto.randomUUID();\n const timeoutMs = opts.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n return new Promise<BroadcastSession | null>((resolve) => {\n const onMsg = (ev: MessageEvent<BroadcastChannelMessage>) => {\n if (ev.data.type === 'offer-session' && ev.data.requestId === requestId && ev.data.expMs > Date.now()) {\n this.channel.removeEventListener('message', onMsg);\n clearTimeout(timer);\n resolve({\n edSeed: ev.data.edSeed,\n secpKey: ev.data.secpKey,\n addresses: ev.data.addresses,\n expMs: ev.data.expMs,\n });\n }\n };\n this.channel.addEventListener('message', onMsg);\n const timer = setTimeout(() => {\n this.channel.removeEventListener('message', onMsg);\n resolve(null);\n }, timeoutMs);\n\n this.channel.postMessage({ type: 'request-session', requestId } as BroadcastChannelMessage);\n });\n }\n\n /** Begin offering this tab's session in response to requests, and handle logouts. */\n start(): void {\n if (this.listening) return;\n this.listening = true;\n this.channel.addEventListener('message', this.onMessage);\n }\n\n stop(): void {\n this.channel.removeEventListener('message', this.onMessage);\n this.listening = false;\n }\n\n /** Notify peers that the user logged out. Peers wipe their sessions. */\n broadcastLogout(): void {\n this.channel.postMessage({ type: 'logout' } as BroadcastChannelMessage);\n }\n\n /** Free the underlying channel handle. Call from unload handlers. */\n close(): void {\n this.stop();\n this.channel.close();\n }\n\n private onMessage = (ev: MessageEvent<BroadcastChannelMessage>): void => {\n const msg = ev.data;\n if (msg.type === 'request-session') {\n const session = this.opts.getSession();\n if (!session || session.expMs <= Date.now()) return;\n this.channel.postMessage({\n type: 'offer-session',\n requestId: msg.requestId,\n edSeed: session.edSeed,\n secpKey: session.secpKey,\n addresses: session.addresses,\n expMs: session.expMs,\n } as BroadcastChannelMessage);\n return;\n }\n if (msg.type === 'logout') {\n this.opts.onLogout?.();\n return;\n }\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/transport/origin.ts","../src/transport/PopupTransport.ts","../src/transport/IframeTransport.ts","../src/EmbedWallet.ts","../src/protocol.ts","../src/transport/PopupHostBridge.ts","../src/transport/BroadcastSessionShare.ts"],"names":["data","pending","WalletError","p"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Origin verification helpers used by both ends of the popup transport.\n * Spec §5.3.\n */\n\n/**\n * Schemes that we accept for origins. Production uses https only; we allow\n * http here so test setups and `localhost:port` work — callers can layer\n * tighter rules (e.g. \"only https in production\") on top.\n */\nexport const ALLOWED_ORIGIN_SCHEMES: readonly string[] = ['https:', 'http:'];\n\n/**\n * Strict origin equality check. Returns true iff both inputs are non-empty,\n * URL-parseable, and have matching `origin` (scheme + host + port).\n */\nexport function isMatchingOrigin(a: string | undefined, b: string | undefined): boolean {\n if (!a || !b) return false;\n try {\n const ua = new URL(a);\n const ub = new URL(b);\n return ua.origin === ub.origin;\n } catch {\n return false;\n }\n}\n","import { WalletError, type WalletErrorCode } from '@cef-ai/wallet-api-client';\nimport type { HostToPopup, PopupToHost } from '../protocol';\nimport { isMatchingOrigin } from './origin';\nimport type { PopupHandle, PopupOpener } from './types';\nimport type { WalletTransport } from './WalletTransport';\n\nexport interface PopupTransportOptions {\n /** Expected origin of the wallet popup, e.g. 'https://wallet.example.com'. */\n walletOrigin: string;\n /** Defaults to `(url, features) => window.open(url, '_blank', features)`. */\n openPopup?: PopupOpener;\n /** Window object hosting the event listener. Defaults to `globalThis.window`. */\n hostWindow?: Window;\n /** Default per-request timeout. Defaults to 60_000 ms. */\n defaultTimeoutMs?: number;\n}\n\ninterface PendingRequest {\n expectedTypes: PopupToHost['type'][];\n resolve: (msg: PopupToHost) => void;\n reject: (err: WalletError) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\nconst DEFAULT_FEATURES = 'width=420,height=640,resizable=yes,scrollbars=yes';\n\n/**\n * Host-side popup transport. Spec §5.\n *\n * Use one `PopupTransport` instance per `EmbedWallet`. The instance owns a\n * single popup window at a time, opens it on demand, auto-reopens on the next\n * `request()` after it's been closed, and correlates each in-flight request\n * by its message `id`.\n *\n * Wire handshake: every freshly opened popup must send `wallet:ready` before\n * this transport will post any `HostToPopup` envelope. Without the handshake,\n * `postMessage` may fire before the popup document has executed its `message`\n * listener and the message is dropped. Outbound messages are queued in\n * `outbox` while `popupReady === false`; `wallet:ready` flushes them.\n */\nexport class PopupTransport implements WalletTransport {\n private readonly opts: Required<PopupTransportOptions>;\n private popup: PopupHandle | null = null;\n private pending: Map<string, PendingRequest> = new Map();\n private listener: ((event: MessageEvent) => void) | null = null;\n private popupReady = false;\n private outbox: HostToPopup[] = [];\n\n constructor(options: PopupTransportOptions) {\n this.opts = {\n openPopup: defaultOpener,\n hostWindow: (globalThis as any).window,\n defaultTimeoutMs: 60_000,\n ...options,\n };\n }\n\n async request<T extends PopupToHost>(\n message: HostToPopup,\n expectedTypes: T['type'][],\n init: { timeoutMs?: number } = {},\n ): Promise<T> {\n if (!this.popup || this.popup.closed) {\n const hostOrigin = (globalThis as any).location?.origin ?? '';\n const url = `${this.opts.walletOrigin}/embed/wallet?origin=${encodeURIComponent(hostOrigin)}`;\n this.popup = this.opts.openPopup(url, DEFAULT_FEATURES);\n if (!this.popup) {\n throw new WalletError('popup-blocked', 'popup window failed to open');\n }\n // Fresh popup: reset handshake state. Any in-flight outbox from a prior\n // popup session is dropped; those requests have their own timers and\n // will fail through the normal timeout path.\n this.popupReady = false;\n this.outbox = [];\n this.ensureListening();\n }\n\n const id = message.id;\n const timeoutMs = init.timeoutMs ?? this.opts.defaultTimeoutMs;\n\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (this.pending.has(id)) {\n this.pending.delete(id);\n // Also drop from the outbox if it never got flushed.\n this.outbox = this.outbox.filter((m) => m.id !== id);\n reject(new WalletError('internal', `request \"${message.type}\" (id=${id}) timed out after ${timeoutMs}ms`));\n }\n }, timeoutMs);\n\n this.pending.set(id, {\n expectedTypes,\n resolve: (msg) => resolve(msg as T),\n reject,\n timer,\n });\n\n if (this.popupReady) {\n this.popup!.postMessage(message, this.opts.walletOrigin);\n } else {\n // Queue until the popup announces `wallet:ready`.\n this.outbox.push(message);\n }\n });\n }\n\n /**\n * Close the popup if open. Immediately rejects any in-flight `request()`\n * calls (mirrors `IframeTransport.close()`) rather than leaving them to\n * time out — a caller that closes the popup mid-request (e.g.\n * `EmbedWallet.register()`'s `finally` block) gets a prompt rejection\n * instead of waiting out the full default 60s timeout.\n */\n close(): void {\n this.rejectAllPending('transport closed');\n if (this.popup && !this.popup.closed) {\n this.popup.close();\n }\n this.popup = null;\n this.popupReady = false;\n this.outbox = [];\n }\n\n /**\n * Tear down the transport entirely. Closes the popup AND removes the host-\n * window message listener. After `destroy()`, the transport instance cannot\n * be reused — callers should drop the reference.\n *\n * Use `close()` if you only want to close the popup but keep the transport\n * alive for a later re-open.\n */\n destroy(): void {\n this.close();\n if (this.listener) {\n this.opts.hostWindow.removeEventListener('message', this.listener);\n this.listener = null;\n }\n }\n\n // ---- internal -------------------------------------------------------------\n\n /** Reject every in-flight request with a `WalletError('internal', reason)`. Idempotent. */\n private rejectAllPending(reason: string): void {\n for (const [id, pending] of this.pending) {\n clearTimeout(pending.timer);\n this.pending.delete(id);\n pending.reject(new WalletError('internal', reason));\n }\n }\n\n private ensureListening(): void {\n if (this.listener) return;\n this.listener = (event: MessageEvent) => this.onMessage(event);\n this.opts.hostWindow.addEventListener('message', this.listener);\n }\n\n private onMessage(event: MessageEvent): void {\n if (!isMatchingOrigin(event.origin, this.opts.walletOrigin)) {\n // Origin-mismatched messages might still target a pending request id —\n // we reject that pending request explicitly so callers get a clear signal\n // rather than waiting for a timeout.\n const data = event.data as PopupToHost | undefined;\n if (data && typeof data.id === 'string' && this.pending.has(data.id)) {\n const pending = this.pending.get(data.id)!;\n this.pending.delete(data.id);\n clearTimeout(pending.timer);\n pending.reject(\n new WalletError(\n 'origin-mismatch',\n `message from \"${event.origin}\" rejected (expected \"${this.opts.walletOrigin}\")`,\n ),\n );\n }\n return;\n }\n\n const data = event.data as PopupToHost | undefined;\n if (!data || typeof data.type !== 'string' || typeof data.id !== 'string') return;\n\n // Handshake: a freshly loaded popup announces itself with `wallet:ready`.\n // Flush any messages that were queued before the popup's listener was wired.\n if (data.type === 'wallet:ready') {\n if (this.popupReady) return;\n this.popupReady = true;\n const toFlush = this.outbox;\n this.outbox = [];\n if (this.popup && !this.popup.closed) {\n for (const m of toFlush) {\n this.popup.postMessage(m, this.opts.walletOrigin);\n }\n }\n return;\n }\n\n const pending = this.pending.get(data.id);\n if (!pending) return;\n\n clearTimeout(pending.timer);\n this.pending.delete(data.id);\n\n if (data.type === 'wallet:error') {\n pending.reject(new WalletError(data.code as WalletErrorCode, data.message, data.traceId));\n return;\n }\n\n if (!pending.expectedTypes.includes(data.type)) {\n pending.reject(\n new WalletError('internal', `received unexpected response type \"${data.type}\" for id \"${data.id}\"`),\n );\n return;\n }\n\n pending.resolve(data);\n }\n}\n\nfunction defaultOpener(url: string, features?: string): PopupHandle | null {\n const w = (globalThis as any).window;\n const opened = w?.open(url, '_blank', features);\n return opened as PopupHandle | null;\n}\n","import { WalletError, type WalletErrorCode } from '@cef-ai/wallet-api-client';\nimport type { HostToPopup, PopupToHost } from '../protocol';\nimport { isMatchingOrigin } from './origin';\nimport type { WalletTransport } from './WalletTransport';\n\nexport interface IframeTransportOptions {\n walletOrigin: string;\n hostWindow?: Window;\n document?: Document;\n defaultTimeoutMs?: number;\n /** Test seam: build the iframe element (happy-dom's contentWindow is null). */\n mountIframe?: (url: string, allow: string) => HTMLIFrameElement;\n /** Test seam: observe overlay visibility transitions without relying on real DOM layout. */\n onOverlay?: (visible: boolean) => void;\n}\ninterface Pending {\n expectedTypes: PopupToHost['type'][];\n resolve: (m: PopupToHost) => void;\n reject: (e: WalletError) => void;\n timer: ReturnType<typeof setTimeout>;\n}\n\nexport class IframeTransport implements WalletTransport {\n private readonly opts: Required<Omit<IframeTransportOptions, 'mountIframe' | 'onOverlay'>> &\n Pick<IframeTransportOptions, 'mountIframe' | 'onOverlay'>;\n private iframe: HTMLIFrameElement | null = null;\n private pending = new Map<string, Pending>();\n private listener: ((e: MessageEvent) => void) | null = null;\n private ready = false;\n private outbox: HostToPopup[] = [];\n private backdrop: HTMLElement | null = null;\n private hiddenCssText = '';\n private overlayVisible = false;\n\n constructor(options: IframeTransportOptions) {\n this.opts = {\n hostWindow: (globalThis as any).window,\n document: (globalThis as any).document,\n defaultTimeoutMs: 60_000,\n mountIframe: options.mountIframe,\n onOverlay: options.onOverlay,\n ...options,\n } as IframeTransport['opts'];\n }\n\n private ensureIframe(): void {\n if (this.iframe) return;\n const hostOrigin = (globalThis as any).location?.origin ?? '';\n const url = `${this.opts.walletOrigin}/embed/wallet?origin=${encodeURIComponent(hostOrigin)}`;\n const allow = `publickey-credentials-get ${this.opts.walletOrigin}`;\n if (this.opts.mountIframe) {\n this.iframe = this.opts.mountIframe(url, allow);\n } else {\n const el = this.opts.document.createElement('iframe');\n el.src = url;\n el.setAttribute('allow', allow);\n el.style.cssText = 'position:fixed;border:0;width:0;height:0;left:-9999px;';\n this.opts.document.body.appendChild(el);\n this.iframe = el;\n }\n this.hiddenCssText = this.iframe.style.cssText ?? '';\n this.ready = false;\n this.outbox = [];\n this.overlayVisible = false;\n this.ensureListening();\n }\n\n private showOverlay(): void {\n if (this.overlayVisible) return;\n this.overlayVisible = true;\n if (this.iframe) {\n const backdrop = this.opts.document.createElement('div');\n backdrop.setAttribute('data-wallet-overlay-backdrop', '');\n backdrop.style.cssText = 'position:fixed;inset:0;background:rgba(0,0,0,.4);z-index:2147483646;';\n this.opts.document.body.appendChild(backdrop);\n this.backdrop = backdrop;\n this.iframe.style.cssText =\n 'position:fixed;border:0;z-index:2147483647;width:min(420px,100vw);height:min(640px,100vh);' +\n 'left:50%;top:50%;transform:translate(-50%,-50%);';\n }\n this.opts.onOverlay?.(true);\n }\n\n private hideOverlay(): void {\n if (!this.overlayVisible) return;\n this.overlayVisible = false;\n this.backdrop?.remove();\n this.backdrop = null;\n if (this.iframe) {\n this.iframe.style.cssText = this.hiddenCssText;\n }\n this.opts.onOverlay?.(false);\n }\n\n private ensureListening(): void {\n if (this.listener) return;\n this.listener = (e: MessageEvent) => this.onMessage(e);\n this.opts.hostWindow.addEventListener('message', this.listener);\n }\n\n async request<T extends PopupToHost>(\n message: HostToPopup,\n expectedTypes: T['type'][],\n init: { timeoutMs?: number } = {},\n ): Promise<T> {\n this.ensureIframe();\n const id = message.id;\n const timeoutMs = init.timeoutMs ?? this.opts.defaultTimeoutMs;\n return new Promise<T>((resolve, reject) => {\n const timer = setTimeout(() => {\n if (this.pending.has(id)) {\n this.pending.delete(id);\n this.outbox = this.outbox.filter((m) => m.id !== id);\n reject(new WalletError('internal', `request \"${message.type}\" (id=${id}) timed out after ${timeoutMs}ms`));\n }\n }, timeoutMs);\n this.pending.set(id, { expectedTypes, resolve: (m) => resolve(m as T), reject, timer });\n if (this.ready) this.postToIframe(message);\n else this.outbox.push(message);\n });\n }\n\n private postToIframe(message: HostToPopup): void {\n this.iframe?.contentWindow?.postMessage(message, this.opts.walletOrigin);\n }\n\n close(): void {\n this.rejectAllPending('transport closed');\n this.backdrop?.remove();\n this.backdrop = null;\n this.overlayVisible = false;\n this.iframe?.remove();\n this.iframe = null;\n this.ready = false;\n this.outbox = [];\n }\n\n destroy(): void {\n this.close();\n if (this.listener) {\n this.opts.hostWindow.removeEventListener('message', this.listener);\n this.listener = null;\n }\n }\n\n private rejectAllPending(reason: string): void {\n for (const [id, p] of this.pending) {\n clearTimeout(p.timer);\n this.pending.delete(id);\n p.reject(new WalletError('internal', reason));\n }\n }\n\n private onMessage(event: MessageEvent): void {\n const data = event.data as PopupToHost | undefined;\n if (!isMatchingOrigin(event.origin, this.opts.walletOrigin)) {\n if (data && typeof data.id === 'string' && this.pending.has(data.id)) {\n const p = this.pending.get(data.id)!;\n this.pending.delete(data.id);\n clearTimeout(p.timer);\n p.reject(\n new WalletError(\n 'origin-mismatch',\n `message from \"${event.origin}\" rejected (expected \"${this.opts.walletOrigin}\")`,\n ),\n );\n }\n return;\n }\n if (!data || typeof data.type !== 'string' || typeof data.id !== 'string') return;\n\n if (data.type === 'wallet:ready') {\n if (this.ready) return;\n this.ready = true;\n const flush = this.outbox;\n this.outbox = [];\n for (const m of flush) this.postToIframe(m);\n return;\n }\n if (data.type === 'wallet:ui:show') {\n this.showOverlay();\n return;\n }\n if (data.type === 'wallet:ui:hide') {\n this.hideOverlay();\n return;\n }\n\n const p = this.pending.get(data.id);\n if (!p) return;\n clearTimeout(p.timer);\n this.pending.delete(data.id);\n if (data.type === 'wallet:error') {\n p.reject(new WalletError(data.code as WalletErrorCode, data.message, data.traceId));\n return;\n }\n if (!p.expectedTypes.includes(data.type)) {\n p.reject(new WalletError('internal', `received unexpected response type \"${data.type}\" for id \"${data.id}\"`));\n return;\n }\n p.resolve(data);\n }\n}\n","import { WalletError } from '@cef-ai/wallet-api-client';\nimport type { Addresses } from '@cef-ai/wallet-identity';\nimport { decodeEd25519Pubkey } from '@cef-ai/wallet-identity';\nimport { EthersSigner, PolkadotSigner, SolanaSigner, type InternalSign } from '@cef-ai/wallet-signers';\nimport type { CefSigner, SignIntent } from './signer';\nimport type {\n EmbedWalletOptions,\n LoginResult,\n DelegationRequest,\n DelegationResult,\n SignerSpec,\n WalletEvent,\n WalletEventListener,\n ApplicationFilter,\n ApplicationBody,\n ApplicationRecord,\n} from './types';\nimport type { AppContext, HostToPopup, PopupToHost } from './protocol';\nimport type { WalletTransport } from './transport/WalletTransport';\nimport type { PopupOpener } from './transport/types';\nimport { PopupTransport } from './transport/PopupTransport';\nimport { IframeTransport } from './transport/IframeTransport';\n\ntype ListenerMap = { [T in WalletEvent['type']]?: Set<WalletEventListener<T>> };\n\n/**\n * Public SDK class. v2.0.0. Spec §4.\n *\n * Drives the popup transport: every method that does meaningful work opens\n * (or reuses) a popup at `walletOrigin/embed/*`, sends a `HostToPopup`\n * message, awaits the matching `PopupToHost` response, and updates local\n * state. See spec §5 for the wire protocol.\n */\nexport class EmbedWallet {\n readonly appId: string;\n readonly walletOrigin: string;\n readonly popup: { width: number; height: number };\n readonly appName: string;\n\n private _addresses: Addresses | null = null;\n private _credentialId: string | null = null;\n private _listeners: ListenerMap = {};\n private readonly transport: WalletTransport;\n private readonly regPopupOpener?: PopupOpener;\n\n constructor(opts: EmbedWalletOptions) {\n // `walletOrigin` is required for real use — the SDK builds a transport\n // pinned to it. The `__internal__.transport` test seam supplies its own\n // origin-pinned transport, so walletOrigin may be omitted in that case.\n const injectedTransport = opts.__internal__?.transport;\n if (!injectedTransport && !opts.walletOrigin) {\n throw new Error('EmbedWallet: `walletOrigin` is required (e.g. https://wallet.example.com).');\n }\n this.appId = opts.appId;\n this.walletOrigin = opts.walletOrigin ?? '';\n this.popup = { width: opts.popup?.width ?? 420, height: opts.popup?.height ?? 640 };\n this.appName = opts.appName ?? '';\n this.regPopupOpener = opts.__internal__?.registerPopupOpener;\n this.transport =\n injectedTransport ??\n (opts.transport === 'popup'\n ? new PopupTransport({ walletOrigin: this.walletOrigin })\n : new IframeTransport({ walletOrigin: this.walletOrigin }));\n }\n\n get isLoggedIn(): boolean {\n return this._addresses !== null;\n }\n get addresses(): Addresses | null {\n return this._addresses;\n }\n get credentialId(): string | null {\n return this._credentialId;\n }\n\n /**\n * Safari blocks WebAuthn `create()` in cross-origin iframes, so `register()`\n * always runs its `wallet:hello` ceremony over a `PopupTransport` — even\n * when the configured transport is the iframe. When the main transport is\n * already a `PopupTransport` it's reused; otherwise a transient one is\n * opened synchronously (within the caller's click) and closed afterward.\n * `login()` and all other ops use the configured transport unchanged.\n */\n async register(opts: { label?: string; name?: string; email?: string } = {}): Promise<LoginResult> {\n if (this.transport instanceof PopupTransport) {\n return this.helloAndAwaitLogin('register', opts);\n }\n const popup = new PopupTransport({\n walletOrigin: this.walletOrigin,\n ...(this.regPopupOpener ? { openPopup: this.regPopupOpener } : {}),\n });\n try {\n return await this.helloAndAwaitLogin('register', opts, popup);\n } finally {\n popup.close();\n }\n }\n\n async login(): Promise<LoginResult> {\n return this.helloAndAwaitLogin('login');\n }\n\n async logout(): Promise<void> {\n if (!this._addresses) {\n this.transport.close();\n return;\n }\n const id = crypto.randomUUID();\n try {\n await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>({ type: 'wallet:logout', id }, [\n 'wallet:result',\n ]);\n } catch (_err) {\n // Ignore — local state still gets cleared below.\n }\n this._addresses = null;\n this._credentialId = null;\n this.transport.close();\n this.emit('logout', { type: 'logout' });\n }\n\n getSigner(spec: { chain: 'evm' }): EthersSigner;\n getSigner(spec: { chain: 'cere' }): PolkadotSigner;\n getSigner(spec: { chain: 'solana' }): SolanaSigner;\n getSigner(spec: SignerSpec): EthersSigner | PolkadotSigner | SolanaSigner;\n getSigner(spec: SignerSpec): EthersSigner | PolkadotSigner | SolanaSigner {\n this.assertLoggedIn('getSigner');\n const sign: InternalSign = async (chain, payload) => {\n const id = crypto.randomUUID();\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:sign', id, chain, payload, requestKind: 'sdk' },\n ['wallet:result'],\n );\n const sig = result.result;\n if (!(sig instanceof Uint8Array)) {\n throw new WalletError('internal', `popup returned non-Uint8Array sign result (got ${typeof sig})`);\n }\n return sig;\n };\n const addresses = this._addresses!;\n switch (spec.chain) {\n case 'evm':\n return new EthersSigner({ address: addresses.evm, sign });\n case 'cere':\n return new PolkadotSigner({ address: addresses.cere, sign });\n case 'solana':\n return new SolanaSigner({ address: addresses.solana, sign });\n default:\n throw new WalletError('validation', `getSigner: unknown chain \"${String((spec as any).chain)}\"`);\n }\n }\n\n /**\n * Expose the wallet as a chain-free `@cef-ai/signer` over the Cere\n * Ed25519 key — the pluggable-signer seam `@cef-ai/account` consumes for DDC\n * and `@cef-ai/chain` adapts for extrinsics.\n *\n * `publicKey` is recovered from the (public) Solana address — no key material\n * leaves the popup's `SessionVault`. `sign(bytes, 'extrinsic', { humanReadable })`\n * routes through the popup's extrinsic-consent screen.\n */\n asSigner(): CefSigner {\n this.assertLoggedIn('asSigner');\n const addresses = this._addresses!;\n const send = async (\n payload: Uint8Array,\n intent: SignIntent | undefined,\n humanReadable: string | undefined,\n ): Promise<Uint8Array> => {\n // `asSigner()` captured the addresses at call time; if the user has since\n // logged out (e.g. cross-tab logout), fail fast here rather than sending a\n // `wallet:sign` the popup would reject with `unauthorized`.\n if (!this.isLoggedIn) {\n throw new WalletError('unauthorized', 'asSigner: wallet is no longer logged in');\n }\n const id = crypto.randomUUID();\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:sign', id, chain: 'cere', payload, requestKind: intent ?? 'sdk', humanReadable },\n ['wallet:result'],\n );\n const sig = result.result;\n if (!(sig instanceof Uint8Array)) {\n throw new WalletError('internal', `popup returned non-Uint8Array sign result (got ${typeof sig})`);\n }\n return sig;\n };\n return {\n type: 'ed25519',\n address: addresses.cere,\n publicKey: decodeEd25519Pubkey(addresses.solana),\n isReady: async () => this.isLoggedIn,\n sign: (bytes, intent, opts) => send(bytes, intent, opts?.humanReadable),\n };\n }\n\n async requestDelegation(req: DelegationRequest): Promise<DelegationResult> {\n this.assertLoggedIn('requestDelegation');\n const id = crypto.randomUUID();\n const scope = {\n capabilities: req.capabilities,\n appId: req.appId,\n agentPubkey: req.agentPubkey,\n constraints: req.constraints,\n };\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:requestDelegation', id, scope, ttl: req.ttl },\n ['wallet:result'],\n );\n return result.result as DelegationResult;\n }\n\n async findApplications(filter: ApplicationFilter = {}): Promise<ApplicationRecord[]> {\n this.assertLoggedIn('findApplications');\n const id = crypto.randomUUID();\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:findApplications', id, appId: filter.appId },\n ['wallet:result'],\n );\n return result.result as ApplicationRecord[];\n }\n\n async saveApplication(body: ApplicationBody): Promise<ApplicationRecord> {\n this.assertLoggedIn('saveApplication');\n const id = crypto.randomUUID();\n const result = await this.transport.request<Extract<PopupToHost, { type: 'wallet:result' }>>(\n { type: 'wallet:saveApplication', id, permissions: body.permissions, email: body.email },\n ['wallet:result'],\n );\n return result.result as ApplicationRecord;\n }\n\n on<T extends WalletEvent['type']>(type: T, listener: WalletEventListener<T>): this {\n const map = this._listeners as Record<string, Set<WalletEventListener<any>>>;\n (map[type] ??= new Set()).add(listener);\n return this;\n }\n\n off<T extends WalletEvent['type']>(type: T, listener: WalletEventListener<T>): this {\n const map = this._listeners as Record<string, Set<WalletEventListener<any>>>;\n map[type]?.delete(listener);\n return this;\n }\n\n /**\n * Tear down the wallet instance. Closes any open popup, removes transport\n * listeners, clears in-memory state. Call from your app's unmount hook.\n *\n * After dispose(), this instance is not reusable — construct a new one.\n */\n dispose(): void {\n this._addresses = null;\n this._credentialId = null;\n this._listeners = {};\n this.transport.destroy();\n }\n\n // ---- private --------------------------------------------------------------\n\n private appContext(): AppContext {\n const origin = typeof window !== 'undefined' ? window.location.origin : '';\n return { appId: this.appId, name: this.appName, origin };\n }\n\n private async helloAndAwaitLogin(\n intent: 'register' | 'login',\n opts: { label?: string; name?: string; email?: string } = {},\n transport: WalletTransport = this.transport,\n ): Promise<LoginResult> {\n const id = crypto.randomUUID();\n const helloMessage: HostToPopup = {\n type: 'wallet:hello',\n id,\n appContext: this.appContext(),\n intent,\n label: opts.label,\n name: opts.name,\n email: opts.email,\n };\n const result = await transport.request<Extract<PopupToHost, { type: 'wallet:login:ok' }>>(helloMessage, [\n 'wallet:login:ok',\n ]);\n this._addresses = result.addresses;\n this._credentialId = result.credentialId;\n this.emit('login', { type: 'login', addresses: result.addresses });\n return { addresses: result.addresses, credentialId: result.credentialId };\n }\n\n private emit<T extends WalletEvent['type']>(type: T, ev: Extract<WalletEvent, { type: T }>): void {\n const set = this._listeners[type] as Set<WalletEventListener<T>> | undefined;\n if (!set) return;\n for (const listener of set) {\n try {\n listener(ev);\n } catch {\n // Listener errors are isolated.\n }\n }\n }\n\n private assertLoggedIn(method: string): void {\n if (!this._addresses) {\n throw new WalletError('unauthorized', `${method}: not logged in`);\n }\n }\n}\n","import type { Addresses, Chain } from '@cef-ai/wallet-identity';\nimport type { WalletErrorCode } from '@cef-ai/wallet-api-client';\nimport type { ApplicationBody, ApplicationFilter, DelegationScope } from './types';\n\nexport interface AppContext {\n appId: string;\n name: string;\n origin: string;\n}\n\n/** Spec §5.2. Messages sent from a host page to a wallet popup. */\nexport type HostToPopup =\n | {\n type: 'wallet:hello';\n id: string;\n appContext: AppContext;\n intent: 'register' | 'login';\n label?: string;\n name?: string;\n email?: string;\n }\n | { type: 'wallet:requestDelegation'; id: string; scope: DelegationScope; ttl: string }\n | { type: 'wallet:sign'; id: string; chain: Chain; payload: Uint8Array; requestKind: string; humanReadable?: string }\n | ({ type: 'wallet:saveApplication'; id: string } & ApplicationBody)\n | ({ type: 'wallet:findApplications'; id: string } & ApplicationFilter)\n | { type: 'wallet:logout'; id: string };\n\n/**\n * Spec §5.2. Messages sent from a wallet popup back to the host.\n *\n * On `wallet:error`, `message` carries the human-readable detail\n * (what `WalletError.detail` returns), NOT the compound `Error.message`\n * (`\"${code}: ${detail}\"`). The compound is reconstructable from `code + message`\n * on the receiving side. Serialisers in the popup MUST send `err.detail ?? ''`,\n * not `err.message`.\n */\nexport type PopupToHost =\n | { type: 'wallet:ready'; id: string }\n | { type: 'wallet:login:ok'; id: string; addresses: Addresses; credentialId: string }\n | { type: 'wallet:result'; id: string; result: unknown }\n | { type: 'wallet:error'; id: string; code: WalletErrorCode; message: string; traceId?: string }\n // One-way UI-visibility signals from the embed doc → host overlay manager\n // (iframe transport). No correlation; `id` preserves the has-id invariant.\n | { type: 'wallet:ui:show'; id: string }\n | { type: 'wallet:ui:hide'; id: string };\n\n/** Spec §5.5. Channel name: `scp-wallet-v2`. Wallet-origin tabs only. */\nexport type BroadcastChannelMessage =\n | { type: 'request-session'; requestId: string }\n | {\n type: 'offer-session';\n requestId: string;\n edSeed: Uint8Array;\n secpKey: Uint8Array;\n addresses: Addresses;\n /** absolute Unix epoch ms when session keys expire */ expMs: number;\n }\n | { type: 'logout' }\n // Keyless, fire-and-forget push: \"a session just became available on this\n // surface\". Carries NO key material — it only tells session-less peers to\n // (re-)issue a `request-session`, which is still the only message that ever\n // moves key material and still only fires in direct response to an explicit\n // request. See `BroadcastSessionShare.announce()`.\n | { type: 'session-available' };\n\nexport const BROADCAST_CHANNEL_NAME = 'scp-wallet-v2';\n","import { WalletError } from '@cef-ai/wallet-api-client';\nimport type { HostToPopup, PopupToHost } from '../protocol';\nimport { isMatchingOrigin } from './origin';\nimport type { PopupMessageHandler } from './types';\n\nexport interface PopupHostBridgeOptions {\n /** Expected origin of the host page (the page that opened this popup). */\n hostOrigin: string;\n /** The window this bridge runs in. Defaults to `globalThis`. */\n popupWindow?: Window;\n /** Which window to post PopupToHost messages to. 'opener' (popup, default) or 'parent' (iframe). */\n replyTo?: 'opener' | 'parent';\n}\n\ntype HandlerMap = {\n [T in HostToPopup['type']]?: PopupMessageHandler<Extract<HostToPopup, { type: T }>>;\n};\n\n/**\n * Popup-side bridge. Spec §5.\n *\n * The wallet SPA constructs one of these at boot, registers handlers via\n * `on(type, fn)`, and calls `start()` to begin listening. Each inbound\n * `HostToPopup` message that matches a registered handler is dispatched;\n * the handler is responsible for calling `bridge.send(...)` to reply.\n *\n * Handlers may throw `WalletError`; the bridge automatically converts the\n * throw into a `wallet:error` response keyed by the inbound message id.\n */\nexport class PopupHostBridge {\n private readonly opts: Required<PopupHostBridgeOptions>;\n private readonly handlers: HandlerMap = {};\n private listener: ((event: MessageEvent) => void) | null = null;\n\n constructor(options: PopupHostBridgeOptions) {\n this.opts = {\n popupWindow: (globalThis as any).window,\n replyTo: 'opener',\n ...options,\n };\n }\n\n /** Register a handler for a specific message type. Replaces any prior handler. */\n on<T extends HostToPopup['type']>(type: T, handler: PopupMessageHandler<Extract<HostToPopup, { type: T }>>): this {\n this.handlers[type] = handler as any;\n return this;\n }\n\n /**\n * Send a `PopupToHost` message back to the opener or parent, depending on\n * `replyTo`. The bridge does not remember the host-window reference itself —\n * it reads the target window each call, so it survives popup re-opens.\n */\n send(message: PopupToHost): void {\n const target: any = this.opts.replyTo === 'parent' ? (globalThis as any).parent : (globalThis as any).opener;\n if (!target || typeof target.postMessage !== 'function') {\n // No target — popup was opened standalone, opener is closed, or not framed.\n return;\n }\n target.postMessage(message, this.opts.hostOrigin);\n }\n\n /**\n * Start listening for inbound messages.\n *\n * If `announceReady` is provided, sends a `wallet:ready` message immediately.\n * Use this when the popup wants to signal \"I'm here\" without waiting for the\n * host's first call.\n */\n start(opts: { announceReady?: { id: string } } = {}): void {\n if (this.listener) return;\n this.listener = (event: MessageEvent) => this.onMessage(event);\n this.opts.popupWindow.addEventListener('message', this.listener);\n if (opts.announceReady) {\n this.send({ type: 'wallet:ready', id: opts.announceReady.id });\n }\n }\n\n stop(): void {\n if (!this.listener) return;\n this.opts.popupWindow.removeEventListener('message', this.listener);\n this.listener = null;\n }\n\n // ---- internal -------------------------------------------------------------\n\n private async onMessage(event: MessageEvent): Promise<void> {\n if (!isMatchingOrigin(event.origin, this.opts.hostOrigin)) {\n // Silently drop.\n return;\n }\n const data = event.data as HostToPopup | undefined;\n if (!data || typeof data.type !== 'string' || typeof data.id !== 'string') return;\n\n const handler = (this.handlers as any)[data.type] as PopupMessageHandler<HostToPopup> | undefined;\n if (!handler) {\n // No handler registered — reply with a typed error.\n this.send({\n type: 'wallet:error',\n id: data.id,\n code: 'internal',\n message: `no handler registered for \"${data.type}\"`,\n });\n return;\n }\n\n try {\n await handler(data, { origin: event.origin });\n } catch (err) {\n if (err instanceof WalletError) {\n this.send({\n type: 'wallet:error',\n id: data.id,\n code: err.code,\n message: err.detail ?? '',\n traceId: err.traceId,\n });\n } else {\n this.send({\n type: 'wallet:error',\n id: data.id,\n code: 'internal',\n message: err instanceof Error ? err.message : String(err),\n });\n }\n }\n }\n}\n","import { BROADCAST_CHANNEL_NAME, type BroadcastChannelMessage } from '../protocol';\nimport type { Addresses } from '@cef-ai/wallet-identity';\n\nexport interface BroadcastSession {\n edSeed: Uint8Array;\n secpKey: Uint8Array;\n addresses: Addresses;\n /** Absolute Unix epoch ms when the session expires. */\n expMs: number;\n}\n\nexport interface BroadcastSessionShareOptions {\n /**\n * Returns the local session if this tab has one to offer. Called whenever\n * another tab broadcasts `request-session`.\n */\n getSession: () => BroadcastSession | null;\n /**\n * Called when another tab broadcasts `session-available` (a keyless,\n * fire-and-forget \"a session just got established\" push — see\n * `announce()`). Session-less listeners should react by issuing a fresh\n * `request()`; this callback never receives key material itself.\n */\n onAvailable?: () => void;\n}\n\nconst DEFAULT_REQUEST_TIMEOUT_MS = 200;\n\n/**\n * Popup-side cross-tab session sharing. Spec §5.5.\n *\n * - `request()`: broadcast `request-session`, wait up to 200ms for an offer.\n * - `start()`: listen for incoming requests; reply with `offer-session` if we\n * have a non-expired session and `getSession()` returns it. Also listens\n * for `session-available` pushes (see `announce()`) and invokes\n * `onAvailable` so a session-less peer can react without polling.\n * - `broadcastLogout()`: notify peers to wipe their sessions too. NOTE: no\n * `BroadcastSessionShare` call site wires a receive-side handler for this\n * today — cross-tab logout is owned exclusively by `IdentityImpl` via its\n * own `CrossTabSync` (`packages/identity/src/CrossTabSync.ts`), which\n * shares this same channel name/message shape by convention. This method\n * (and the `'logout'` message type) stays for public-API compatibility\n * (`@cef-ai/wallet` is published) but intentionally has no paired\n * `onLogout` option — wiring one would double-handle logout alongside\n * `CrossTabSync`. See `ARCHITECTURE.md` Key invariants.\n * - `announce()`: notify peers that THIS tab just established a session, so a\n * session-less peer can immediately issue its own `request()` rather than\n * waiting on a one-shot timer that may have already elapsed. Carries no key\n * material — only `request()`/`offer-session` ever move keys, and only in\n * direct response to an explicit request. This keeps the push trigger and\n * the key transfer on two separate, independently-gated messages.\n *\n * Channel name is the spec-locked `scp-wallet-v2`. Only wallet-origin popups\n * join. Host pages do not participate.\n */\nexport class BroadcastSessionShare {\n private readonly channel: BroadcastChannel;\n private readonly opts: BroadcastSessionShareOptions;\n private listening = false;\n\n constructor(opts: BroadcastSessionShareOptions) {\n this.opts = opts;\n this.channel = new BroadcastChannel(BROADCAST_CHANNEL_NAME);\n }\n\n /**\n * Broadcast a `request-session` and wait for an `offer-session` from another\n * tab. Resolves with the offered session, or null if nobody offered before\n * the timeout.\n */\n async request(opts: { timeoutMs?: number } = {}): Promise<BroadcastSession | null> {\n const requestId = crypto.randomUUID();\n const timeoutMs = opts.timeoutMs ?? DEFAULT_REQUEST_TIMEOUT_MS;\n\n return new Promise<BroadcastSession | null>((resolve) => {\n const onMsg = (ev: MessageEvent<BroadcastChannelMessage>) => {\n if (ev.data.type === 'offer-session' && ev.data.requestId === requestId && ev.data.expMs > Date.now()) {\n this.channel.removeEventListener('message', onMsg);\n clearTimeout(timer);\n resolve({\n edSeed: ev.data.edSeed,\n secpKey: ev.data.secpKey,\n addresses: ev.data.addresses,\n expMs: ev.data.expMs,\n });\n }\n };\n this.channel.addEventListener('message', onMsg);\n const timer = setTimeout(() => {\n this.channel.removeEventListener('message', onMsg);\n resolve(null);\n }, timeoutMs);\n\n this.channel.postMessage({ type: 'request-session', requestId } as BroadcastChannelMessage);\n });\n }\n\n /**\n * Begin offering this tab's session in response to requests, and invoke\n * `onAvailable` on incoming `session-available` pushes. Callers that only\n * care about `onAvailable` (no session to offer) still call `start()` —\n * `getSession()` returning `null` simply means `request-session` replies\n * are skipped.\n */\n start(): void {\n if (this.listening) return;\n this.listening = true;\n this.channel.addEventListener('message', this.onMessage);\n }\n\n stop(): void {\n this.channel.removeEventListener('message', this.onMessage);\n this.listening = false;\n }\n\n /**\n * Notify peers that the user logged out. Kept for public-API compatibility;\n * no `BroadcastSessionShare` instance currently handles the receive side\n * (see class doc) — cross-tab logout is `CrossTabSync`'s responsibility.\n */\n broadcastLogout(): void {\n this.channel.postMessage({ type: 'logout' } as BroadcastChannelMessage);\n }\n\n /**\n * Notify peers that this tab just established a session (register/login\n * completed). Carries NO key material — it is purely a push trigger that\n * tells session-less peers to issue their own `request()`. Key material\n * still only ever moves as an `offer-session` reply to an explicit\n * `request-session`; `announce()` does not bypass that gate.\n */\n announce(): void {\n this.channel.postMessage({ type: 'session-available' } as BroadcastChannelMessage);\n }\n\n /** Free the underlying channel handle. Call from unload handlers. */\n close(): void {\n this.stop();\n this.channel.close();\n }\n\n private onMessage = (ev: MessageEvent<BroadcastChannelMessage>): void => {\n const msg = ev.data;\n if (msg.type === 'request-session') {\n const session = this.opts.getSession();\n if (!session || session.expMs <= Date.now()) return;\n this.channel.postMessage({\n type: 'offer-session',\n requestId: msg.requestId,\n edSeed: session.edSeed,\n secpKey: session.secpKey,\n addresses: session.addresses,\n expMs: session.expMs,\n } as BroadcastChannelMessage);\n return;\n }\n if (msg.type === 'session-available') {\n this.opts.onAvailable?.();\n return;\n }\n };\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@cef-ai/wallet",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.1.0",
|
|
4
4
|
"description": "Embed SCP Wallet into a host application — passkey-native, no MetaMask, no seed phrases.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"repository": {
|
|
@@ -39,8 +39,8 @@
|
|
|
39
39
|
],
|
|
40
40
|
"dependencies": {
|
|
41
41
|
"@cef-ai/wallet-api-client": "1.0.0",
|
|
42
|
-
"@cef-ai/wallet-identity": "1.
|
|
43
|
-
"@cef-ai/wallet-signers": "1.0.
|
|
42
|
+
"@cef-ai/wallet-identity": "1.1.0",
|
|
43
|
+
"@cef-ai/wallet-signers": "1.0.1"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"happy-dom": "^15.7.0"
|