@canton-network/core-provider-dapp
Advanced tools
+169
-137
@@ -1,145 +0,177 @@ | ||
| 'use strict'; | ||
| var SpliceWalletJSONRPCDAppAPI = require('@canton-network/core-wallet-dapp-rpc-client'); | ||
| var coreSpliceProvider = require('@canton-network/core-splice-provider'); | ||
| var coreRpcTransport = require('@canton-network/core-rpc-transport'); | ||
| var SpliceWalletJSONRPCRemoteDAppAPI = require('@canton-network/core-wallet-dapp-remote-rpc-client'); | ||
| var coreTypes = require('@canton-network/core-types'); | ||
| function _interopDefault (e) { return e && e.__esModule ? e : { default: e }; } | ||
| var SpliceWalletJSONRPCDAppAPI__default = /*#__PURE__*/_interopDefault(SpliceWalletJSONRPCDAppAPI); | ||
| var SpliceWalletJSONRPCRemoteDAppAPI__default = /*#__PURE__*/_interopDefault(SpliceWalletJSONRPCRemoteDAppAPI); | ||
| Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" }); | ||
| //#region \0rolldown/runtime.js | ||
| var __create = Object.create; | ||
| var __defProp = Object.defineProperty; | ||
| var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
| var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
| var DappSyncProvider = class extends coreSpliceProvider.AbstractProvider { | ||
| constructor(transport) { | ||
| super(); | ||
| __publicField(this, "client"); | ||
| const rpcTransport = transport ?? new coreRpcTransport.WindowTransport(window); | ||
| this.client = new SpliceWalletJSONRPCDAppAPI__default.default(rpcTransport); | ||
| if (rpcTransport instanceof coreRpcTransport.WindowTransport) { | ||
| rpcTransport.onNotification((method, params) => { | ||
| this.emit(method, params); | ||
| }); | ||
| } | ||
| } | ||
| async request(args) { | ||
| return await this.client.request(args); | ||
| } | ||
| var __getOwnPropDesc = Object.getOwnPropertyDescriptor; | ||
| var __getOwnPropNames = Object.getOwnPropertyNames; | ||
| var __getProtoOf = Object.getPrototypeOf; | ||
| var __hasOwnProp = Object.prototype.hasOwnProperty; | ||
| var __copyProps = (to, from, except, desc) => { | ||
| if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) { | ||
| key = keys[i]; | ||
| if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, { | ||
| get: ((k) => from[k]).bind(null, key), | ||
| enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable | ||
| }); | ||
| } | ||
| return to; | ||
| }; | ||
| var connection = null; | ||
| var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(isNodeMode || !mod || !mod.__esModule || !__hasOwnProp.call(mod, "default") ? __defProp(target, "default", { | ||
| value: mod, | ||
| enumerable: true | ||
| }) : target, mod)); | ||
| //#endregion | ||
| let _canton_network_core_wallet_dapp_rpc_client = require("@canton-network/core-wallet-dapp-rpc-client"); | ||
| _canton_network_core_wallet_dapp_rpc_client = __toESM(_canton_network_core_wallet_dapp_rpc_client, 1); | ||
| let _canton_network_core_splice_provider = require("@canton-network/core-splice-provider"); | ||
| let _canton_network_core_rpc_transport = require("@canton-network/core-rpc-transport"); | ||
| let _canton_network_core_wallet_dapp_remote_rpc_client = require("@canton-network/core-wallet-dapp-remote-rpc-client"); | ||
| _canton_network_core_wallet_dapp_remote_rpc_client = __toESM(_canton_network_core_wallet_dapp_remote_rpc_client, 1); | ||
| let _canton_network_core_types = require("@canton-network/core-types"); | ||
| //#region \0@oxc-project+runtime@0.142.0/helpers/esm/typeof.js | ||
| function _typeof(o) { | ||
| "@babel/helpers - typeof"; | ||
| return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) { | ||
| return typeof o; | ||
| } : function(o) { | ||
| return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; | ||
| }, _typeof(o); | ||
| } | ||
| //#endregion | ||
| //#region \0@oxc-project+runtime@0.142.0/helpers/esm/toPrimitive.js | ||
| function toPrimitive(t, r) { | ||
| if ("object" != _typeof(t) || !t) return t; | ||
| var e = t[Symbol.toPrimitive]; | ||
| if (void 0 !== e) { | ||
| var i = e.call(t, r || "default"); | ||
| if ("object" != _typeof(i)) return i; | ||
| throw new TypeError("@@toPrimitive must return a primitive value."); | ||
| } | ||
| return ("string" === r ? String : Number)(t); | ||
| } | ||
| //#endregion | ||
| //#region \0@oxc-project+runtime@0.142.0/helpers/esm/toPropertyKey.js | ||
| function toPropertyKey(t) { | ||
| var i = toPrimitive(t, "string"); | ||
| return "symbol" == _typeof(i) ? i : i + ""; | ||
| } | ||
| //#endregion | ||
| //#region \0@oxc-project+runtime@0.142.0/helpers/esm/defineProperty.js | ||
| function _defineProperty(e, r, t) { | ||
| return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, { | ||
| value: t, | ||
| enumerable: !0, | ||
| configurable: !0, | ||
| writable: !0 | ||
| }) : e[r] = t, e; | ||
| } | ||
| //#endregion | ||
| //#region src/DappSyncProvider.ts | ||
| var DappSyncProvider = class extends _canton_network_core_splice_provider.AbstractProvider { | ||
| constructor(transport) { | ||
| super(); | ||
| _defineProperty(this, "client", void 0); | ||
| const rpcTransport = transport ?? new _canton_network_core_rpc_transport.WindowTransport(window); | ||
| this.client = new _canton_network_core_wallet_dapp_rpc_client.default(rpcTransport); | ||
| if (rpcTransport instanceof _canton_network_core_rpc_transport.WindowTransport) rpcTransport.onNotification((method, params) => { | ||
| this.emit(method, params); | ||
| }); | ||
| } | ||
| async request(args) { | ||
| return await this.client.request(args); | ||
| } | ||
| }; | ||
| //#endregion | ||
| //#region src/DappAsyncProvider.ts | ||
| let connection = null; | ||
| function parseSSEData(data) { | ||
| try { | ||
| const parsed = JSON.parse(data); | ||
| return Array.isArray(parsed) ? parsed : [parsed]; | ||
| } catch { | ||
| return [data]; | ||
| } | ||
| try { | ||
| const parsed = JSON.parse(data); | ||
| return Array.isArray(parsed) ? parsed : [parsed]; | ||
| } catch { | ||
| return [data]; | ||
| } | ||
| } | ||
| var DappAsyncProvider = class extends coreSpliceProvider.AbstractProvider { | ||
| constructor(url, sessionToken) { | ||
| super(); | ||
| __publicField(this, "sessionToken"); | ||
| __publicField(this, "url"); | ||
| __publicField(this, "client"); | ||
| __publicField(this, "status"); | ||
| __publicField(this, "sseForwarder", (event, args) => { | ||
| this.emit(event, ...args); | ||
| }); | ||
| this.url = typeof url === "string" ? new URL(url) : url; | ||
| if (sessionToken) { | ||
| this.sessionToken = sessionToken; | ||
| this.openSSE(this.url, sessionToken); | ||
| } | ||
| this.client = this.createClient(sessionToken); | ||
| window.addEventListener("message", async (event) => { | ||
| if (!coreTypes.isSpliceMessageEvent(event)) return; | ||
| if (event.data.type === coreTypes.WalletEvent.SPLICE_WALLET_IDP_AUTH_SUCCESS) { | ||
| this.sessionToken = event.data.token; | ||
| this.client = this.createClient(this.sessionToken); | ||
| this.openSSE(this.url, event.data.token); | ||
| this.request({ method: "status" }).then((status) => { | ||
| if ( | ||
| // TODO this is not ideal as it's possible for same object to have different keys order after stringify | ||
| JSON.stringify(status.session) !== JSON.stringify(this.status) | ||
| ) { | ||
| this.emit("statusChanged", status); | ||
| this.status = status.session; | ||
| } | ||
| }).catch((err) => { | ||
| console.error( | ||
| "Error requesting status after auth:", | ||
| err | ||
| ); | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
| createClient(sessionToken) { | ||
| const transport = new coreRpcTransport.HttpTransport(this.url, sessionToken); | ||
| return new SpliceWalletJSONRPCRemoteDAppAPI__default.default(transport); | ||
| } | ||
| openSSE(url, token) { | ||
| const sseUrl = new URL("events", url.toString().replace(/\/?$/, "/")); | ||
| sseUrl.searchParams.set("token", token); | ||
| const sseUrlString = sseUrl.toString(); | ||
| if (connection && (token !== connection.token || sseUrlString !== connection.url)) { | ||
| connection.eventSource.close(); | ||
| connection = null; | ||
| } | ||
| if (!connection) { | ||
| const eventSource = new EventSource(sseUrlString); | ||
| const dispatchToProviders = (eventName) => (event) => { | ||
| const args = parseSSEData(event.data); | ||
| connection?.listeners.forEach((listener) => { | ||
| listener(eventName, args); | ||
| }); | ||
| }; | ||
| eventSource.onmessage = dispatchToProviders("message"); | ||
| eventSource.addEventListener( | ||
| "accountsChanged", | ||
| dispatchToProviders("accountsChanged") | ||
| ); | ||
| eventSource.addEventListener( | ||
| "statusChanged", | ||
| dispatchToProviders("statusChanged") | ||
| ); | ||
| eventSource.addEventListener( | ||
| "connected", | ||
| dispatchToProviders("connected") | ||
| ); | ||
| eventSource.addEventListener( | ||
| "txChanged", | ||
| dispatchToProviders("txChanged") | ||
| ); | ||
| eventSource.addEventListener( | ||
| "messageSignature", | ||
| dispatchToProviders("messageSignature") | ||
| ); | ||
| eventSource.onerror = () => { | ||
| if (connection?.url === sseUrlString) { | ||
| connection.eventSource.close(); | ||
| connection = null; | ||
| } | ||
| }; | ||
| connection = { | ||
| eventSource, | ||
| url: sseUrlString, | ||
| token, | ||
| listeners: /* @__PURE__ */ new Set() | ||
| }; | ||
| } | ||
| connection.listeners.add(this.sseForwarder); | ||
| } | ||
| async request(args) { | ||
| return await this.client.request(args); | ||
| } | ||
| var DappAsyncProvider = class extends _canton_network_core_splice_provider.AbstractProvider { | ||
| createClient(sessionToken) { | ||
| const transport = new _canton_network_core_rpc_transport.HttpTransport(this.url, sessionToken); | ||
| return new _canton_network_core_wallet_dapp_remote_rpc_client.default(transport); | ||
| } | ||
| openSSE(url, token) { | ||
| const sseUrl = new URL("events", url.toString().replace(/\/?$/, "/")); | ||
| sseUrl.searchParams.set("token", token); | ||
| const sseUrlString = sseUrl.toString(); | ||
| if (connection && (token !== connection.token || sseUrlString !== connection.url)) { | ||
| connection.eventSource.close(); | ||
| connection = null; | ||
| } | ||
| if (!connection) { | ||
| const eventSource = new EventSource(sseUrlString); | ||
| const dispatchToProviders = (eventName) => (event) => { | ||
| const args = parseSSEData(event.data); | ||
| connection?.listeners.forEach((listener) => { | ||
| listener(eventName, args); | ||
| }); | ||
| }; | ||
| eventSource.onmessage = dispatchToProviders("message"); | ||
| eventSource.addEventListener("accountsChanged", dispatchToProviders("accountsChanged")); | ||
| eventSource.addEventListener("statusChanged", dispatchToProviders("statusChanged")); | ||
| eventSource.addEventListener("connected", dispatchToProviders("connected")); | ||
| eventSource.addEventListener("txChanged", dispatchToProviders("txChanged")); | ||
| eventSource.addEventListener("messageSignature", dispatchToProviders("messageSignature")); | ||
| eventSource.onerror = () => { | ||
| if (connection?.url === sseUrlString) { | ||
| connection.eventSource.close(); | ||
| connection = null; | ||
| } | ||
| }; | ||
| connection = { | ||
| eventSource, | ||
| url: sseUrlString, | ||
| token, | ||
| listeners: /* @__PURE__ */ new Set() | ||
| }; | ||
| } | ||
| connection.listeners.add(this.sseForwarder); | ||
| } | ||
| constructor(url, sessionToken) { | ||
| super(); | ||
| _defineProperty(this, "sessionToken", void 0); | ||
| _defineProperty(this, "url", void 0); | ||
| _defineProperty(this, "client", void 0); | ||
| _defineProperty(this, "status", void 0); | ||
| _defineProperty(this, "sseForwarder", (event, args) => { | ||
| this.emit(event, ...args); | ||
| }); | ||
| this.url = typeof url === "string" ? new URL(url) : url; | ||
| if (sessionToken) { | ||
| this.sessionToken = sessionToken; | ||
| this.openSSE(this.url, sessionToken); | ||
| } | ||
| this.client = this.createClient(sessionToken); | ||
| window.addEventListener("message", async (event) => { | ||
| if (!(0, _canton_network_core_types.isSpliceMessageEvent)(event)) return; | ||
| if (event.data.type === _canton_network_core_types.WalletEvent.SPLICE_WALLET_IDP_AUTH_SUCCESS) { | ||
| this.sessionToken = event.data.token; | ||
| this.client = this.createClient(this.sessionToken); | ||
| this.openSSE(this.url, event.data.token); | ||
| this.request({ method: "status" }).then((status) => { | ||
| if (JSON.stringify(status.session) !== JSON.stringify(this.status)) { | ||
| this.emit("statusChanged", status); | ||
| this.status = status.session; | ||
| } | ||
| }).catch((err) => { | ||
| console.error("Error requesting status after auth:", err); | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
| async request(args) { | ||
| return await this.client.request(args); | ||
| } | ||
| }; | ||
| //#endregion | ||
| exports.DappAsyncProvider = DappAsyncProvider; | ||
| exports.DappSyncProvider = DappSyncProvider; | ||
| //# sourceMappingURL=index.cjs.map | ||
| //# sourceMappingURL=index.cjs.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/DappSyncProvider.ts","../src/DappAsyncProvider.ts"],"names":["AbstractProvider","WindowTransport","SpliceWalletJSONRPCDAppAPI","isSpliceMessageEvent","WalletEvent","HttpTransport","SpliceWalletJSONRPCRemoteDAppAPI"],"mappings":";;;;;;;;;;;;;;;;AAaO,IAAM,gBAAA,GAAN,cAA+BA,mCAAA,CAA+B;AAAA,EAGjE,YAAY,SAAA,EAA0B;AAClC,IAAA,KAAA,EAAM;AAHV,IAAA,aAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AAIJ,IAAA,MAAM,YAAA,GAAe,SAAA,IAAa,IAAIC,gCAAA,CAAgB,MAAM,CAAA;AAC5D,IAAA,IAAA,CAAK,MAAA,GAAS,IAAIC,2CAAA,CAA2B,YAAY,CAAA;AAKzD,IAAA,IAAI,wBAAwBD,gCAAA,EAAiB;AACzC,MAAA,YAAA,CAAa,cAAA,CAAe,CAAC,MAAA,EAAQ,MAAA,KAAW;AAC5C,QAAA,IAAA,CAAK,IAAA,CAAK,QAAQ,MAAM,CAAA;AAAA,MAC5B,CAAC,CAAA;AAAA,IACL;AAAA,EACJ;AAAA,EAEA,MAAa,QACT,IAAA,EACkC;AAClC,IAAA,OAAO,MAAM,IAAA,CAAK,MAAA,CAAO,OAAA,CAAW,IAAI,CAAA;AAAA,EAC5C;AACJ;ACZA,IAAI,UAAA,GAAyB,IAAA;AAE7B,SAAS,aAAa,IAAA,EAAyB;AAC3C,EAAA,IAAI;AACA,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,KAAA,CAAM,IAAI,CAAA;AAC9B,IAAA,OAAO,MAAM,OAAA,CAAQ,MAAM,CAAA,GAAI,MAAA,GAAS,CAAC,MAAM,CAAA;AAAA,EACnD,CAAA,CAAA,MAAQ;AACJ,IAAA,OAAO,CAAC,IAAI,CAAA;AAAA,EAChB;AACJ;AAEO,IAAM,iBAAA,GAAN,cAAgCD,mCAAAA,CAAoC;AAAA,EAiFvE,WAAA,CAAY,KAAmB,YAAA,EAAuB;AAClD,IAAA,KAAA,EAAM;AAjFV,IAAA,aAAA,CAAA,IAAA,EAAQ,cAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,KAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAQ,QAAA,CAAA;AACR,IAAA,aAAA,CAAA,IAAA,EAAiB,cAAA,EAAe,CAAC,KAAA,EAAe,IAAA,KAAoB;AAChE,MAAA,IAAA,CAAK,IAAA,CAAK,KAAA,EAAO,GAAG,IAAI,CAAA;AAAA,IAC5B,CAAA,CAAA;AA4EI,IAAA,IAAA,CAAK,MAAM,OAAO,GAAA,KAAQ,WAAW,IAAI,GAAA,CAAI,GAAG,CAAA,GAAI,GAAA;AAEpD,IAAA,IAAI,YAAA,EAAc;AACd,MAAA,IAAA,CAAK,YAAA,GAAe,YAAA;AACpB,MAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,GAAA,EAAK,YAAY,CAAA;AAAA,IACvC;AAEA,IAAA,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,YAAA,CAAa,YAAY,CAAA;AAG5C,IAAA,MAAA,CAAO,gBAAA,CAAiB,SAAA,EAAW,OAAO,KAAA,KAAU;AAChD,MAAA,IAAI,CAACG,8BAAA,CAAqB,KAAK,CAAA,EAAG;AAElC,MAAA,IACI,KAAA,CAAM,IAAA,CAAK,IAAA,KAASC,qBAAA,CAAY,8BAAA,EAClC;AACE,QAAA,IAAA,CAAK,YAAA,GAAe,MAAM,IAAA,CAAK,KAAA;AAC/B,QAAA,IAAA,CAAK,MAAA,GAAS,IAAA,CAAK,YAAA,CAAa,IAAA,CAAK,YAAY,CAAA;AACjD,QAAA,IAAA,CAAK,OAAA,CAAQ,IAAA,CAAK,GAAA,EAAK,KAAA,CAAM,KAAK,KAAK,CAAA;AAKvC,QAAA,IAAA,CAAK,OAAA,CAAQ,EAAE,MAAA,EAAQ,QAAA,EAAU,CAAA,CAC5B,IAAA,CAAK,CAAC,MAAA,KAAW;AAEd,UAAA;AAAA;AAAA,YAEI,IAAA,CAAK,UAAU,MAAA,CAAO,OAAO,MAC7B,IAAA,CAAK,SAAA,CAAU,KAAK,MAAM;AAAA,YAC5B;AACE,YAAA,IAAA,CAAK,IAAA,CAAK,iBAAiB,MAAM,CAAA;AACjC,YAAA,IAAA,CAAK,SAAS,MAAA,CAAO,OAAA;AAAA,UACzB;AAAA,QACJ,CAAC,CAAA,CACA,KAAA,CAAM,CAAC,GAAA,KAAQ;AACZ,UAAA,OAAA,CAAQ,KAAA;AAAA,YACJ,qCAAA;AAAA,YACA;AAAA,WACJ;AAAA,QACJ,CAAC,CAAA;AAAA,MACT;AAAA,IACJ,CAAC,CAAA;AAAA,EACL;AAAA,EArHQ,aACJ,YAAA,EACgC;AAChC,IAAA,MAAM,SAAA,GAAY,IAAIC,8BAAA,CAAc,IAAA,CAAK,KAAK,YAAY,CAAA;AAC1D,IAAA,OAAO,IAAIC,kDAAiC,SAAS,CAAA;AAAA,EACzD;AAAA,EAEQ,OAAA,CAAQ,KAAU,KAAA,EAAqB;AAC3C,IAAA,MAAM,MAAA,GAAS,IAAI,GAAA,CAAI,QAAA,EAAU,GAAA,CAAI,UAAS,CAAE,OAAA,CAAQ,MAAA,EAAQ,GAAG,CAAC,CAAA;AACpE,IAAA,MAAA,CAAO,YAAA,CAAa,GAAA,CAAI,OAAA,EAAS,KAAK,CAAA;AACtC,IAAA,MAAM,YAAA,GAAe,OAAO,QAAA,EAAS;AAGrC,IAAA,IACI,eACC,KAAA,KAAU,UAAA,CAAW,KAAA,IAAS,YAAA,KAAiB,WAAW,GAAA,CAAA,EAC7D;AACE,MAAA,UAAA,CAAW,YAAY,KAAA,EAAM;AAC7B,MAAA,UAAA,GAAa,IAAA;AAAA,IACjB;AAEA,IAAA,IAAI,CAAC,UAAA,EAAY;AACb,MAAA,MAAM,WAAA,GAAc,IAAI,WAAA,CAAY,YAAY,CAAA;AAChD,MAAA,MAAM,mBAAA,GACF,CAAC,SAAA,KAAsB,CAAC,KAAA,KAAwB;AAC5C,QAAA,MAAM,IAAA,GAAO,YAAA,CAAa,KAAA,CAAM,IAAI,CAAA;AACpC,QAAA,UAAA,EAAY,SAAA,CAAU,OAAA,CAAQ,CAAC,QAAA,KAAa;AACxC,UAAA,QAAA,CAAS,WAAW,IAAI,CAAA;AAAA,QAC5B,CAAC,CAAA;AAAA,MACL,CAAA;AAEJ,MAAA,WAAA,CAAY,SAAA,GAAY,oBAAoB,SAAS,CAAA;AAErD,MAAA,WAAA,CAAY,gBAAA;AAAA,QACR,iBAAA;AAAA,QACA,oBAAoB,iBAAiB;AAAA,OACzC;AACA,MAAA,WAAA,CAAY,gBAAA;AAAA,QACR,eAAA;AAAA,QACA,oBAAoB,eAAe;AAAA,OACvC;AACA,MAAA,WAAA,CAAY,gBAAA;AAAA,QACR,WAAA;AAAA,QACA,oBAAoB,WAAW;AAAA,OACnC;AACA,MAAA,WAAA,CAAY,gBAAA;AAAA,QACR,WAAA;AAAA,QACA,oBAAoB,WAAW;AAAA,OACnC;AACA,MAAA,WAAA,CAAY,gBAAA;AAAA,QACR,kBAAA;AAAA,QACA,oBAAoB,kBAAkB;AAAA,OAC1C;AAEA,MAAA,WAAA,CAAY,UAAU,MAAM;AACxB,QAAA,IAAI,UAAA,EAAY,QAAQ,YAAA,EAAc;AAClC,UAAA,UAAA,CAAW,YAAY,KAAA,EAAM;AAC7B,UAAA,UAAA,GAAa,IAAA;AAAA,QACjB;AAAA,MACJ,CAAA;AAEA,MAAA,UAAA,GAAa;AAAA,QACT,WAAA;AAAA,QACA,GAAA,EAAK,YAAA;AAAA,QACL,KAAA;AAAA,QACA,SAAA,sBAAe,GAAA;AAAI,OACvB;AAAA,IACJ;AAEA,IAAA,UAAA,CAAW,SAAA,CAAU,GAAA,CAAI,IAAA,CAAK,YAAY,CAAA;AAAA,EAC9C;AAAA,EAiDA,MAAa,QACT,IAAA,EACuC;AACvC,IAAA,OAAO,MAAM,IAAA,CAAK,MAAA,CAAO,OAAA,CAAW,IAAI,CAAA;AAAA,EAC5C;AACJ","file":"index.cjs","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport SpliceWalletJSONRPCDAppAPI, {\n RpcTypes as DappRpcTypes,\n} from '@canton-network/core-wallet-dapp-rpc-client'\nimport { AbstractProvider } from '@canton-network/core-splice-provider'\nimport { RequestArgs } from '@canton-network/core-types'\nimport {\n RpcTransport,\n WindowTransport,\n} from '@canton-network/core-rpc-transport'\n\nexport class DappSyncProvider extends AbstractProvider<DappRpcTypes> {\n private client: SpliceWalletJSONRPCDAppAPI\n\n constructor(transport?: RpcTransport) {\n super()\n const rpcTransport = transport ?? new WindowTransport(window)\n this.client = new SpliceWalletJSONRPCDAppAPI(rpcTransport)\n // CIP-103 events (txChanged, accountsChanged, statusChanged,\n // connected) arrive as wallet-pushed notifications on the window\n // transport; bridge them into the AbstractProvider listener map so\n // provider.on(event, listener) delivers them as the CIP requires.\n if (rpcTransport instanceof WindowTransport) {\n rpcTransport.onNotification((method, params) => {\n this.emit(method, params)\n })\n }\n }\n\n public async request<M extends keyof DappRpcTypes>(\n args: RequestArgs<DappRpcTypes, M>\n ): Promise<DappRpcTypes[M]['result']> {\n return await this.client.request<M>(args)\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport SpliceWalletJSONRPCRemoteDAppAPI, {\n RpcTypes as DappAsyncRpcTypes,\n Session,\n} from '@canton-network/core-wallet-dapp-remote-rpc-client'\nimport { AbstractProvider } from '@canton-network/core-splice-provider'\nimport { HttpTransport } from '@canton-network/core-rpc-transport'\nimport {\n isSpliceMessageEvent,\n RequestArgs,\n WalletEvent,\n} from '@canton-network/core-types'\n\n// Maintain a global SSE connection in-memory to avoid multiple connections\n// per DappAsyncProvider instance.\ntype GatewaySSE = {\n url: string\n token: string\n eventSource: EventSource\n listeners: Set<(event: string, args: unknown[]) => void>\n} | null\n\nlet connection: GatewaySSE = null\n\nfunction parseSSEData(data: string): unknown[] {\n try {\n const parsed = JSON.parse(data)\n return Array.isArray(parsed) ? parsed : [parsed]\n } catch {\n return [data]\n }\n}\n\nexport class DappAsyncProvider extends AbstractProvider<DappAsyncRpcTypes> {\n private sessionToken?: string\n private url: URL\n private client: SpliceWalletJSONRPCRemoteDAppAPI\n private status?: Session | undefined\n private readonly sseForwarder = (event: string, args: unknown[]) => {\n this.emit(event, ...args)\n }\n\n private createClient(\n sessionToken?: string\n ): SpliceWalletJSONRPCRemoteDAppAPI {\n const transport = new HttpTransport(this.url, sessionToken)\n return new SpliceWalletJSONRPCRemoteDAppAPI(transport)\n }\n\n private openSSE(url: URL, token: string): void {\n const sseUrl = new URL('events', url.toString().replace(/\\/?$/, '/'))\n sseUrl.searchParams.set('token', token)\n const sseUrlString = sseUrl.toString()\n\n // Reconnect if the URL or token has changed\n if (\n connection &&\n (token !== connection.token || sseUrlString !== connection.url)\n ) {\n connection.eventSource.close()\n connection = null\n }\n\n if (!connection) {\n const eventSource = new EventSource(sseUrlString)\n const dispatchToProviders =\n (eventName: string) => (event: MessageEvent) => {\n const args = parseSSEData(event.data)\n connection?.listeners.forEach((listener) => {\n listener(eventName, args)\n })\n }\n\n eventSource.onmessage = dispatchToProviders('message')\n\n eventSource.addEventListener(\n 'accountsChanged',\n dispatchToProviders('accountsChanged')\n )\n eventSource.addEventListener(\n 'statusChanged',\n dispatchToProviders('statusChanged')\n )\n eventSource.addEventListener(\n 'connected',\n dispatchToProviders('connected')\n )\n eventSource.addEventListener(\n 'txChanged',\n dispatchToProviders('txChanged')\n )\n eventSource.addEventListener(\n 'messageSignature',\n dispatchToProviders('messageSignature')\n )\n\n eventSource.onerror = () => {\n if (connection?.url === sseUrlString) {\n connection.eventSource.close()\n connection = null\n }\n }\n\n connection = {\n eventSource,\n url: sseUrlString,\n token,\n listeners: new Set(),\n }\n }\n\n connection.listeners.add(this.sseForwarder)\n }\n\n constructor(url: URL | string, sessionToken?: string) {\n super()\n this.url = typeof url === 'string' ? new URL(url) : url\n\n if (sessionToken) {\n this.sessionToken = sessionToken\n this.openSSE(this.url, sessionToken)\n }\n\n this.client = this.createClient(sessionToken)\n\n // Listen for the auth success event sent from the WK UI popup to the SDK running in the parent window.\n window.addEventListener('message', async (event) => {\n if (!isSpliceMessageEvent(event)) return\n\n if (\n event.data.type === WalletEvent.SPLICE_WALLET_IDP_AUTH_SUCCESS\n ) {\n this.sessionToken = event.data.token\n this.client = this.createClient(this.sessionToken)\n this.openSSE(this.url, event.data.token)\n\n // We requery the status explicitly here, as it's not guaranteed that the socket will be open & authenticated\n // before the `statusChanged` event is fired from the `addSession` RPC call. The dappApi.StatusResult and\n // dappApi.StatusEvent are mapped manually to avoid dependency.\n this.request({ method: 'status' })\n .then((status) => {\n //for some reason comparing the objects directly dosent work as intended\n if (\n // TODO this is not ideal as it's possible for same object to have different keys order after stringify\n JSON.stringify(status.session) !==\n JSON.stringify(this.status)\n ) {\n this.emit('statusChanged', status)\n this.status = status.session\n }\n })\n .catch((err) => {\n console.error(\n 'Error requesting status after auth:',\n err\n )\n })\n }\n })\n }\n\n public async request<M extends keyof DappAsyncRpcTypes>(\n args: RequestArgs<DappAsyncRpcTypes, M>\n ): Promise<DappAsyncRpcTypes[M]['result']> {\n return await this.client.request<M>(args)\n }\n}\n"]} | ||
| {"version":3,"file":"index.cjs","names":["AbstractProvider","WindowTransport","SpliceWalletJSONRPCDAppAPI","AbstractProvider","HttpTransport","SpliceWalletJSONRPCRemoteDAppAPI","isSpliceMessageEvent","WalletEvent"],"sources":["../src/DappSyncProvider.ts","../src/DappAsyncProvider.ts"],"sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport SpliceWalletJSONRPCDAppAPI, {\n RpcTypes as DappRpcTypes,\n} from '@canton-network/core-wallet-dapp-rpc-client'\nimport { AbstractProvider } from '@canton-network/core-splice-provider'\nimport { RequestArgs } from '@canton-network/core-types'\nimport {\n RpcTransport,\n WindowTransport,\n} from '@canton-network/core-rpc-transport'\n\nexport class DappSyncProvider extends AbstractProvider<DappRpcTypes> {\n private client: SpliceWalletJSONRPCDAppAPI\n\n constructor(transport?: RpcTransport) {\n super()\n const rpcTransport = transport ?? new WindowTransport(window)\n this.client = new SpliceWalletJSONRPCDAppAPI(rpcTransport)\n // CIP-103 events (txChanged, accountsChanged, statusChanged,\n // connected) arrive as wallet-pushed notifications on the window\n // transport; bridge them into the AbstractProvider listener map so\n // provider.on(event, listener) delivers them as the CIP requires.\n if (rpcTransport instanceof WindowTransport) {\n rpcTransport.onNotification((method, params) => {\n this.emit(method, params)\n })\n }\n }\n\n public async request<M extends keyof DappRpcTypes>(\n args: RequestArgs<DappRpcTypes, M>\n ): Promise<DappRpcTypes[M]['result']> {\n return await this.client.request<M>(args)\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport SpliceWalletJSONRPCRemoteDAppAPI, {\n RpcTypes as DappAsyncRpcTypes,\n Session,\n} from '@canton-network/core-wallet-dapp-remote-rpc-client'\nimport { AbstractProvider } from '@canton-network/core-splice-provider'\nimport { HttpTransport } from '@canton-network/core-rpc-transport'\nimport {\n isSpliceMessageEvent,\n RequestArgs,\n WalletEvent,\n} from '@canton-network/core-types'\n\n// Maintain a global SSE connection in-memory to avoid multiple connections\n// per DappAsyncProvider instance.\ntype GatewaySSE = {\n url: string\n token: string\n eventSource: EventSource\n listeners: Set<(event: string, args: unknown[]) => void>\n} | null\n\nlet connection: GatewaySSE = null\n\nfunction parseSSEData(data: string): unknown[] {\n try {\n const parsed = JSON.parse(data)\n return Array.isArray(parsed) ? parsed : [parsed]\n } catch {\n return [data]\n }\n}\n\nexport class DappAsyncProvider extends AbstractProvider<DappAsyncRpcTypes> {\n private sessionToken?: string\n private url: URL\n private client: SpliceWalletJSONRPCRemoteDAppAPI\n private status?: Session | undefined\n private readonly sseForwarder = (event: string, args: unknown[]) => {\n this.emit(event, ...args)\n }\n\n private createClient(\n sessionToken?: string\n ): SpliceWalletJSONRPCRemoteDAppAPI {\n const transport = new HttpTransport(this.url, sessionToken)\n return new SpliceWalletJSONRPCRemoteDAppAPI(transport)\n }\n\n private openSSE(url: URL, token: string): void {\n const sseUrl = new URL('events', url.toString().replace(/\\/?$/, '/'))\n sseUrl.searchParams.set('token', token)\n const sseUrlString = sseUrl.toString()\n\n // Reconnect if the URL or token has changed\n if (\n connection &&\n (token !== connection.token || sseUrlString !== connection.url)\n ) {\n connection.eventSource.close()\n connection = null\n }\n\n if (!connection) {\n const eventSource = new EventSource(sseUrlString)\n const dispatchToProviders =\n (eventName: string) => (event: MessageEvent) => {\n const args = parseSSEData(event.data)\n connection?.listeners.forEach((listener) => {\n listener(eventName, args)\n })\n }\n\n eventSource.onmessage = dispatchToProviders('message')\n\n eventSource.addEventListener(\n 'accountsChanged',\n dispatchToProviders('accountsChanged')\n )\n eventSource.addEventListener(\n 'statusChanged',\n dispatchToProviders('statusChanged')\n )\n eventSource.addEventListener(\n 'connected',\n dispatchToProviders('connected')\n )\n eventSource.addEventListener(\n 'txChanged',\n dispatchToProviders('txChanged')\n )\n eventSource.addEventListener(\n 'messageSignature',\n dispatchToProviders('messageSignature')\n )\n\n eventSource.onerror = () => {\n if (connection?.url === sseUrlString) {\n connection.eventSource.close()\n connection = null\n }\n }\n\n connection = {\n eventSource,\n url: sseUrlString,\n token,\n listeners: new Set(),\n }\n }\n\n connection.listeners.add(this.sseForwarder)\n }\n\n constructor(url: URL | string, sessionToken?: string) {\n super()\n this.url = typeof url === 'string' ? new URL(url) : url\n\n if (sessionToken) {\n this.sessionToken = sessionToken\n this.openSSE(this.url, sessionToken)\n }\n\n this.client = this.createClient(sessionToken)\n\n // Listen for the auth success event sent from the WK UI popup to the SDK running in the parent window.\n window.addEventListener('message', async (event) => {\n if (!isSpliceMessageEvent(event)) return\n\n if (\n event.data.type === WalletEvent.SPLICE_WALLET_IDP_AUTH_SUCCESS\n ) {\n this.sessionToken = event.data.token\n this.client = this.createClient(this.sessionToken)\n this.openSSE(this.url, event.data.token)\n\n // We requery the status explicitly here, as it's not guaranteed that the socket will be open & authenticated\n // before the `statusChanged` event is fired from the `addSession` RPC call. The dappApi.StatusResult and\n // dappApi.StatusEvent are mapped manually to avoid dependency.\n this.request({ method: 'status' })\n .then((status) => {\n //for some reason comparing the objects directly dosent work as intended\n if (\n // TODO this is not ideal as it's possible for same object to have different keys order after stringify\n JSON.stringify(status.session) !==\n JSON.stringify(this.status)\n ) {\n this.emit('statusChanged', status)\n this.status = status.session\n }\n })\n .catch((err) => {\n console.error(\n 'Error requesting status after auth:',\n err\n )\n })\n }\n })\n }\n\n public async request<M extends keyof DappAsyncRpcTypes>(\n args: RequestArgs<DappAsyncRpcTypes, M>\n ): Promise<DappAsyncRpcTypes[M]['result']> {\n return await this.client.request<M>(args)\n }\n}\n"],"mappings":"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"} |
+143
-129
@@ -1,137 +0,151 @@ | ||
| import SpliceWalletJSONRPCDAppAPI from '@canton-network/core-wallet-dapp-rpc-client'; | ||
| import { AbstractProvider } from '@canton-network/core-splice-provider'; | ||
| import { WindowTransport, HttpTransport } from '@canton-network/core-rpc-transport'; | ||
| import SpliceWalletJSONRPCRemoteDAppAPI from '@canton-network/core-wallet-dapp-remote-rpc-client'; | ||
| import { isSpliceMessageEvent, WalletEvent } from '@canton-network/core-types'; | ||
| var __defProp = Object.defineProperty; | ||
| var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; | ||
| var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); | ||
| import SpliceWalletJSONRPCDAppAPI from "@canton-network/core-wallet-dapp-rpc-client"; | ||
| import { AbstractProvider } from "@canton-network/core-splice-provider"; | ||
| import { HttpTransport, WindowTransport } from "@canton-network/core-rpc-transport"; | ||
| import SpliceWalletJSONRPCRemoteDAppAPI from "@canton-network/core-wallet-dapp-remote-rpc-client"; | ||
| import { WalletEvent, isSpliceMessageEvent } from "@canton-network/core-types"; | ||
| //#region \0@oxc-project+runtime@0.142.0/helpers/esm/typeof.js | ||
| function _typeof(o) { | ||
| "@babel/helpers - typeof"; | ||
| return _typeof = "function" == typeof Symbol && "symbol" == typeof Symbol.iterator ? function(o) { | ||
| return typeof o; | ||
| } : function(o) { | ||
| return o && "function" == typeof Symbol && o.constructor === Symbol && o !== Symbol.prototype ? "symbol" : typeof o; | ||
| }, _typeof(o); | ||
| } | ||
| //#endregion | ||
| //#region \0@oxc-project+runtime@0.142.0/helpers/esm/toPrimitive.js | ||
| function toPrimitive(t, r) { | ||
| if ("object" != _typeof(t) || !t) return t; | ||
| var e = t[Symbol.toPrimitive]; | ||
| if (void 0 !== e) { | ||
| var i = e.call(t, r || "default"); | ||
| if ("object" != _typeof(i)) return i; | ||
| throw new TypeError("@@toPrimitive must return a primitive value."); | ||
| } | ||
| return ("string" === r ? String : Number)(t); | ||
| } | ||
| //#endregion | ||
| //#region \0@oxc-project+runtime@0.142.0/helpers/esm/toPropertyKey.js | ||
| function toPropertyKey(t) { | ||
| var i = toPrimitive(t, "string"); | ||
| return "symbol" == _typeof(i) ? i : i + ""; | ||
| } | ||
| //#endregion | ||
| //#region \0@oxc-project+runtime@0.142.0/helpers/esm/defineProperty.js | ||
| function _defineProperty(e, r, t) { | ||
| return (r = toPropertyKey(r)) in e ? Object.defineProperty(e, r, { | ||
| value: t, | ||
| enumerable: !0, | ||
| configurable: !0, | ||
| writable: !0 | ||
| }) : e[r] = t, e; | ||
| } | ||
| //#endregion | ||
| //#region src/DappSyncProvider.ts | ||
| var DappSyncProvider = class extends AbstractProvider { | ||
| constructor(transport) { | ||
| super(); | ||
| __publicField(this, "client"); | ||
| const rpcTransport = transport ?? new WindowTransport(window); | ||
| this.client = new SpliceWalletJSONRPCDAppAPI(rpcTransport); | ||
| if (rpcTransport instanceof WindowTransport) { | ||
| rpcTransport.onNotification((method, params) => { | ||
| this.emit(method, params); | ||
| }); | ||
| } | ||
| } | ||
| async request(args) { | ||
| return await this.client.request(args); | ||
| } | ||
| constructor(transport) { | ||
| super(); | ||
| _defineProperty(this, "client", void 0); | ||
| const rpcTransport = transport ?? new WindowTransport(window); | ||
| this.client = new SpliceWalletJSONRPCDAppAPI(rpcTransport); | ||
| if (rpcTransport instanceof WindowTransport) rpcTransport.onNotification((method, params) => { | ||
| this.emit(method, params); | ||
| }); | ||
| } | ||
| async request(args) { | ||
| return await this.client.request(args); | ||
| } | ||
| }; | ||
| var connection = null; | ||
| //#endregion | ||
| //#region src/DappAsyncProvider.ts | ||
| let connection = null; | ||
| function parseSSEData(data) { | ||
| try { | ||
| const parsed = JSON.parse(data); | ||
| return Array.isArray(parsed) ? parsed : [parsed]; | ||
| } catch { | ||
| return [data]; | ||
| } | ||
| try { | ||
| const parsed = JSON.parse(data); | ||
| return Array.isArray(parsed) ? parsed : [parsed]; | ||
| } catch { | ||
| return [data]; | ||
| } | ||
| } | ||
| var DappAsyncProvider = class extends AbstractProvider { | ||
| constructor(url, sessionToken) { | ||
| super(); | ||
| __publicField(this, "sessionToken"); | ||
| __publicField(this, "url"); | ||
| __publicField(this, "client"); | ||
| __publicField(this, "status"); | ||
| __publicField(this, "sseForwarder", (event, args) => { | ||
| this.emit(event, ...args); | ||
| }); | ||
| this.url = typeof url === "string" ? new URL(url) : url; | ||
| if (sessionToken) { | ||
| this.sessionToken = sessionToken; | ||
| this.openSSE(this.url, sessionToken); | ||
| } | ||
| this.client = this.createClient(sessionToken); | ||
| window.addEventListener("message", async (event) => { | ||
| if (!isSpliceMessageEvent(event)) return; | ||
| if (event.data.type === WalletEvent.SPLICE_WALLET_IDP_AUTH_SUCCESS) { | ||
| this.sessionToken = event.data.token; | ||
| this.client = this.createClient(this.sessionToken); | ||
| this.openSSE(this.url, event.data.token); | ||
| this.request({ method: "status" }).then((status) => { | ||
| if ( | ||
| // TODO this is not ideal as it's possible for same object to have different keys order after stringify | ||
| JSON.stringify(status.session) !== JSON.stringify(this.status) | ||
| ) { | ||
| this.emit("statusChanged", status); | ||
| this.status = status.session; | ||
| } | ||
| }).catch((err) => { | ||
| console.error( | ||
| "Error requesting status after auth:", | ||
| err | ||
| ); | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
| createClient(sessionToken) { | ||
| const transport = new HttpTransport(this.url, sessionToken); | ||
| return new SpliceWalletJSONRPCRemoteDAppAPI(transport); | ||
| } | ||
| openSSE(url, token) { | ||
| const sseUrl = new URL("events", url.toString().replace(/\/?$/, "/")); | ||
| sseUrl.searchParams.set("token", token); | ||
| const sseUrlString = sseUrl.toString(); | ||
| if (connection && (token !== connection.token || sseUrlString !== connection.url)) { | ||
| connection.eventSource.close(); | ||
| connection = null; | ||
| } | ||
| if (!connection) { | ||
| const eventSource = new EventSource(sseUrlString); | ||
| const dispatchToProviders = (eventName) => (event) => { | ||
| const args = parseSSEData(event.data); | ||
| connection?.listeners.forEach((listener) => { | ||
| listener(eventName, args); | ||
| }); | ||
| }; | ||
| eventSource.onmessage = dispatchToProviders("message"); | ||
| eventSource.addEventListener( | ||
| "accountsChanged", | ||
| dispatchToProviders("accountsChanged") | ||
| ); | ||
| eventSource.addEventListener( | ||
| "statusChanged", | ||
| dispatchToProviders("statusChanged") | ||
| ); | ||
| eventSource.addEventListener( | ||
| "connected", | ||
| dispatchToProviders("connected") | ||
| ); | ||
| eventSource.addEventListener( | ||
| "txChanged", | ||
| dispatchToProviders("txChanged") | ||
| ); | ||
| eventSource.addEventListener( | ||
| "messageSignature", | ||
| dispatchToProviders("messageSignature") | ||
| ); | ||
| eventSource.onerror = () => { | ||
| if (connection?.url === sseUrlString) { | ||
| connection.eventSource.close(); | ||
| connection = null; | ||
| } | ||
| }; | ||
| connection = { | ||
| eventSource, | ||
| url: sseUrlString, | ||
| token, | ||
| listeners: /* @__PURE__ */ new Set() | ||
| }; | ||
| } | ||
| connection.listeners.add(this.sseForwarder); | ||
| } | ||
| async request(args) { | ||
| return await this.client.request(args); | ||
| } | ||
| createClient(sessionToken) { | ||
| const transport = new HttpTransport(this.url, sessionToken); | ||
| return new SpliceWalletJSONRPCRemoteDAppAPI(transport); | ||
| } | ||
| openSSE(url, token) { | ||
| const sseUrl = new URL("events", url.toString().replace(/\/?$/, "/")); | ||
| sseUrl.searchParams.set("token", token); | ||
| const sseUrlString = sseUrl.toString(); | ||
| if (connection && (token !== connection.token || sseUrlString !== connection.url)) { | ||
| connection.eventSource.close(); | ||
| connection = null; | ||
| } | ||
| if (!connection) { | ||
| const eventSource = new EventSource(sseUrlString); | ||
| const dispatchToProviders = (eventName) => (event) => { | ||
| const args = parseSSEData(event.data); | ||
| connection?.listeners.forEach((listener) => { | ||
| listener(eventName, args); | ||
| }); | ||
| }; | ||
| eventSource.onmessage = dispatchToProviders("message"); | ||
| eventSource.addEventListener("accountsChanged", dispatchToProviders("accountsChanged")); | ||
| eventSource.addEventListener("statusChanged", dispatchToProviders("statusChanged")); | ||
| eventSource.addEventListener("connected", dispatchToProviders("connected")); | ||
| eventSource.addEventListener("txChanged", dispatchToProviders("txChanged")); | ||
| eventSource.addEventListener("messageSignature", dispatchToProviders("messageSignature")); | ||
| eventSource.onerror = () => { | ||
| if (connection?.url === sseUrlString) { | ||
| connection.eventSource.close(); | ||
| connection = null; | ||
| } | ||
| }; | ||
| connection = { | ||
| eventSource, | ||
| url: sseUrlString, | ||
| token, | ||
| listeners: /* @__PURE__ */ new Set() | ||
| }; | ||
| } | ||
| connection.listeners.add(this.sseForwarder); | ||
| } | ||
| constructor(url, sessionToken) { | ||
| super(); | ||
| _defineProperty(this, "sessionToken", void 0); | ||
| _defineProperty(this, "url", void 0); | ||
| _defineProperty(this, "client", void 0); | ||
| _defineProperty(this, "status", void 0); | ||
| _defineProperty(this, "sseForwarder", (event, args) => { | ||
| this.emit(event, ...args); | ||
| }); | ||
| this.url = typeof url === "string" ? new URL(url) : url; | ||
| if (sessionToken) { | ||
| this.sessionToken = sessionToken; | ||
| this.openSSE(this.url, sessionToken); | ||
| } | ||
| this.client = this.createClient(sessionToken); | ||
| window.addEventListener("message", async (event) => { | ||
| if (!isSpliceMessageEvent(event)) return; | ||
| if (event.data.type === WalletEvent.SPLICE_WALLET_IDP_AUTH_SUCCESS) { | ||
| this.sessionToken = event.data.token; | ||
| this.client = this.createClient(this.sessionToken); | ||
| this.openSSE(this.url, event.data.token); | ||
| this.request({ method: "status" }).then((status) => { | ||
| if (JSON.stringify(status.session) !== JSON.stringify(this.status)) { | ||
| this.emit("statusChanged", status); | ||
| this.status = status.session; | ||
| } | ||
| }).catch((err) => { | ||
| console.error("Error requesting status after auth:", err); | ||
| }); | ||
| } | ||
| }); | ||
| } | ||
| async request(args) { | ||
| return await this.client.request(args); | ||
| } | ||
| }; | ||
| //#endregion | ||
| export { DappAsyncProvider, DappSyncProvider }; | ||
| export { DappAsyncProvider, DappSyncProvider }; | ||
| //# sourceMappingURL=index.js.map | ||
| //# sourceMappingURL=index.js.map |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"sources":["../src/DappSyncProvider.ts","../src/DappAsyncProvider.ts"],"names":["AbstractProvider"],"mappings":"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","file":"index.js","sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport SpliceWalletJSONRPCDAppAPI, {\n RpcTypes as DappRpcTypes,\n} from '@canton-network/core-wallet-dapp-rpc-client'\nimport { AbstractProvider } from '@canton-network/core-splice-provider'\nimport { RequestArgs } from '@canton-network/core-types'\nimport {\n RpcTransport,\n WindowTransport,\n} from '@canton-network/core-rpc-transport'\n\nexport class DappSyncProvider extends AbstractProvider<DappRpcTypes> {\n private client: SpliceWalletJSONRPCDAppAPI\n\n constructor(transport?: RpcTransport) {\n super()\n const rpcTransport = transport ?? new WindowTransport(window)\n this.client = new SpliceWalletJSONRPCDAppAPI(rpcTransport)\n // CIP-103 events (txChanged, accountsChanged, statusChanged,\n // connected) arrive as wallet-pushed notifications on the window\n // transport; bridge them into the AbstractProvider listener map so\n // provider.on(event, listener) delivers them as the CIP requires.\n if (rpcTransport instanceof WindowTransport) {\n rpcTransport.onNotification((method, params) => {\n this.emit(method, params)\n })\n }\n }\n\n public async request<M extends keyof DappRpcTypes>(\n args: RequestArgs<DappRpcTypes, M>\n ): Promise<DappRpcTypes[M]['result']> {\n return await this.client.request<M>(args)\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport SpliceWalletJSONRPCRemoteDAppAPI, {\n RpcTypes as DappAsyncRpcTypes,\n Session,\n} from '@canton-network/core-wallet-dapp-remote-rpc-client'\nimport { AbstractProvider } from '@canton-network/core-splice-provider'\nimport { HttpTransport } from '@canton-network/core-rpc-transport'\nimport {\n isSpliceMessageEvent,\n RequestArgs,\n WalletEvent,\n} from '@canton-network/core-types'\n\n// Maintain a global SSE connection in-memory to avoid multiple connections\n// per DappAsyncProvider instance.\ntype GatewaySSE = {\n url: string\n token: string\n eventSource: EventSource\n listeners: Set<(event: string, args: unknown[]) => void>\n} | null\n\nlet connection: GatewaySSE = null\n\nfunction parseSSEData(data: string): unknown[] {\n try {\n const parsed = JSON.parse(data)\n return Array.isArray(parsed) ? parsed : [parsed]\n } catch {\n return [data]\n }\n}\n\nexport class DappAsyncProvider extends AbstractProvider<DappAsyncRpcTypes> {\n private sessionToken?: string\n private url: URL\n private client: SpliceWalletJSONRPCRemoteDAppAPI\n private status?: Session | undefined\n private readonly sseForwarder = (event: string, args: unknown[]) => {\n this.emit(event, ...args)\n }\n\n private createClient(\n sessionToken?: string\n ): SpliceWalletJSONRPCRemoteDAppAPI {\n const transport = new HttpTransport(this.url, sessionToken)\n return new SpliceWalletJSONRPCRemoteDAppAPI(transport)\n }\n\n private openSSE(url: URL, token: string): void {\n const sseUrl = new URL('events', url.toString().replace(/\\/?$/, '/'))\n sseUrl.searchParams.set('token', token)\n const sseUrlString = sseUrl.toString()\n\n // Reconnect if the URL or token has changed\n if (\n connection &&\n (token !== connection.token || sseUrlString !== connection.url)\n ) {\n connection.eventSource.close()\n connection = null\n }\n\n if (!connection) {\n const eventSource = new EventSource(sseUrlString)\n const dispatchToProviders =\n (eventName: string) => (event: MessageEvent) => {\n const args = parseSSEData(event.data)\n connection?.listeners.forEach((listener) => {\n listener(eventName, args)\n })\n }\n\n eventSource.onmessage = dispatchToProviders('message')\n\n eventSource.addEventListener(\n 'accountsChanged',\n dispatchToProviders('accountsChanged')\n )\n eventSource.addEventListener(\n 'statusChanged',\n dispatchToProviders('statusChanged')\n )\n eventSource.addEventListener(\n 'connected',\n dispatchToProviders('connected')\n )\n eventSource.addEventListener(\n 'txChanged',\n dispatchToProviders('txChanged')\n )\n eventSource.addEventListener(\n 'messageSignature',\n dispatchToProviders('messageSignature')\n )\n\n eventSource.onerror = () => {\n if (connection?.url === sseUrlString) {\n connection.eventSource.close()\n connection = null\n }\n }\n\n connection = {\n eventSource,\n url: sseUrlString,\n token,\n listeners: new Set(),\n }\n }\n\n connection.listeners.add(this.sseForwarder)\n }\n\n constructor(url: URL | string, sessionToken?: string) {\n super()\n this.url = typeof url === 'string' ? new URL(url) : url\n\n if (sessionToken) {\n this.sessionToken = sessionToken\n this.openSSE(this.url, sessionToken)\n }\n\n this.client = this.createClient(sessionToken)\n\n // Listen for the auth success event sent from the WK UI popup to the SDK running in the parent window.\n window.addEventListener('message', async (event) => {\n if (!isSpliceMessageEvent(event)) return\n\n if (\n event.data.type === WalletEvent.SPLICE_WALLET_IDP_AUTH_SUCCESS\n ) {\n this.sessionToken = event.data.token\n this.client = this.createClient(this.sessionToken)\n this.openSSE(this.url, event.data.token)\n\n // We requery the status explicitly here, as it's not guaranteed that the socket will be open & authenticated\n // before the `statusChanged` event is fired from the `addSession` RPC call. The dappApi.StatusResult and\n // dappApi.StatusEvent are mapped manually to avoid dependency.\n this.request({ method: 'status' })\n .then((status) => {\n //for some reason comparing the objects directly dosent work as intended\n if (\n // TODO this is not ideal as it's possible for same object to have different keys order after stringify\n JSON.stringify(status.session) !==\n JSON.stringify(this.status)\n ) {\n this.emit('statusChanged', status)\n this.status = status.session\n }\n })\n .catch((err) => {\n console.error(\n 'Error requesting status after auth:',\n err\n )\n })\n }\n })\n }\n\n public async request<M extends keyof DappAsyncRpcTypes>(\n args: RequestArgs<DappAsyncRpcTypes, M>\n ): Promise<DappAsyncRpcTypes[M]['result']> {\n return await this.client.request<M>(args)\n }\n}\n"]} | ||
| {"version":3,"file":"index.js","names":[],"sources":["../src/DappSyncProvider.ts","../src/DappAsyncProvider.ts"],"sourcesContent":["// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport SpliceWalletJSONRPCDAppAPI, {\n RpcTypes as DappRpcTypes,\n} from '@canton-network/core-wallet-dapp-rpc-client'\nimport { AbstractProvider } from '@canton-network/core-splice-provider'\nimport { RequestArgs } from '@canton-network/core-types'\nimport {\n RpcTransport,\n WindowTransport,\n} from '@canton-network/core-rpc-transport'\n\nexport class DappSyncProvider extends AbstractProvider<DappRpcTypes> {\n private client: SpliceWalletJSONRPCDAppAPI\n\n constructor(transport?: RpcTransport) {\n super()\n const rpcTransport = transport ?? new WindowTransport(window)\n this.client = new SpliceWalletJSONRPCDAppAPI(rpcTransport)\n // CIP-103 events (txChanged, accountsChanged, statusChanged,\n // connected) arrive as wallet-pushed notifications on the window\n // transport; bridge them into the AbstractProvider listener map so\n // provider.on(event, listener) delivers them as the CIP requires.\n if (rpcTransport instanceof WindowTransport) {\n rpcTransport.onNotification((method, params) => {\n this.emit(method, params)\n })\n }\n }\n\n public async request<M extends keyof DappRpcTypes>(\n args: RequestArgs<DappRpcTypes, M>\n ): Promise<DappRpcTypes[M]['result']> {\n return await this.client.request<M>(args)\n }\n}\n","// Copyright (c) 2025-2026 Digital Asset (Switzerland) GmbH and/or its affiliates. All rights reserved.\n// SPDX-License-Identifier: Apache-2.0\n\nimport SpliceWalletJSONRPCRemoteDAppAPI, {\n RpcTypes as DappAsyncRpcTypes,\n Session,\n} from '@canton-network/core-wallet-dapp-remote-rpc-client'\nimport { AbstractProvider } from '@canton-network/core-splice-provider'\nimport { HttpTransport } from '@canton-network/core-rpc-transport'\nimport {\n isSpliceMessageEvent,\n RequestArgs,\n WalletEvent,\n} from '@canton-network/core-types'\n\n// Maintain a global SSE connection in-memory to avoid multiple connections\n// per DappAsyncProvider instance.\ntype GatewaySSE = {\n url: string\n token: string\n eventSource: EventSource\n listeners: Set<(event: string, args: unknown[]) => void>\n} | null\n\nlet connection: GatewaySSE = null\n\nfunction parseSSEData(data: string): unknown[] {\n try {\n const parsed = JSON.parse(data)\n return Array.isArray(parsed) ? parsed : [parsed]\n } catch {\n return [data]\n }\n}\n\nexport class DappAsyncProvider extends AbstractProvider<DappAsyncRpcTypes> {\n private sessionToken?: string\n private url: URL\n private client: SpliceWalletJSONRPCRemoteDAppAPI\n private status?: Session | undefined\n private readonly sseForwarder = (event: string, args: unknown[]) => {\n this.emit(event, ...args)\n }\n\n private createClient(\n sessionToken?: string\n ): SpliceWalletJSONRPCRemoteDAppAPI {\n const transport = new HttpTransport(this.url, sessionToken)\n return new SpliceWalletJSONRPCRemoteDAppAPI(transport)\n }\n\n private openSSE(url: URL, token: string): void {\n const sseUrl = new URL('events', url.toString().replace(/\\/?$/, '/'))\n sseUrl.searchParams.set('token', token)\n const sseUrlString = sseUrl.toString()\n\n // Reconnect if the URL or token has changed\n if (\n connection &&\n (token !== connection.token || sseUrlString !== connection.url)\n ) {\n connection.eventSource.close()\n connection = null\n }\n\n if (!connection) {\n const eventSource = new EventSource(sseUrlString)\n const dispatchToProviders =\n (eventName: string) => (event: MessageEvent) => {\n const args = parseSSEData(event.data)\n connection?.listeners.forEach((listener) => {\n listener(eventName, args)\n })\n }\n\n eventSource.onmessage = dispatchToProviders('message')\n\n eventSource.addEventListener(\n 'accountsChanged',\n dispatchToProviders('accountsChanged')\n )\n eventSource.addEventListener(\n 'statusChanged',\n dispatchToProviders('statusChanged')\n )\n eventSource.addEventListener(\n 'connected',\n dispatchToProviders('connected')\n )\n eventSource.addEventListener(\n 'txChanged',\n dispatchToProviders('txChanged')\n )\n eventSource.addEventListener(\n 'messageSignature',\n dispatchToProviders('messageSignature')\n )\n\n eventSource.onerror = () => {\n if (connection?.url === sseUrlString) {\n connection.eventSource.close()\n connection = null\n }\n }\n\n connection = {\n eventSource,\n url: sseUrlString,\n token,\n listeners: new Set(),\n }\n }\n\n connection.listeners.add(this.sseForwarder)\n }\n\n constructor(url: URL | string, sessionToken?: string) {\n super()\n this.url = typeof url === 'string' ? new URL(url) : url\n\n if (sessionToken) {\n this.sessionToken = sessionToken\n this.openSSE(this.url, sessionToken)\n }\n\n this.client = this.createClient(sessionToken)\n\n // Listen for the auth success event sent from the WK UI popup to the SDK running in the parent window.\n window.addEventListener('message', async (event) => {\n if (!isSpliceMessageEvent(event)) return\n\n if (\n event.data.type === WalletEvent.SPLICE_WALLET_IDP_AUTH_SUCCESS\n ) {\n this.sessionToken = event.data.token\n this.client = this.createClient(this.sessionToken)\n this.openSSE(this.url, event.data.token)\n\n // We requery the status explicitly here, as it's not guaranteed that the socket will be open & authenticated\n // before the `statusChanged` event is fired from the `addSession` RPC call. The dappApi.StatusResult and\n // dappApi.StatusEvent are mapped manually to avoid dependency.\n this.request({ method: 'status' })\n .then((status) => {\n //for some reason comparing the objects directly dosent work as intended\n if (\n // TODO this is not ideal as it's possible for same object to have different keys order after stringify\n JSON.stringify(status.session) !==\n JSON.stringify(this.status)\n ) {\n this.emit('statusChanged', status)\n this.status = status.session\n }\n })\n .catch((err) => {\n console.error(\n 'Error requesting status after auth:',\n err\n )\n })\n }\n })\n }\n\n public async request<M extends keyof DappAsyncRpcTypes>(\n args: RequestArgs<DappAsyncRpcTypes, M>\n ): Promise<DappAsyncRpcTypes[M]['result']> {\n return await this.client.request<M>(args)\n }\n}\n"],"mappings":"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"} |
+14
-14
| { | ||
| "name": "@canton-network/core-provider-dapp", | ||
| "version": "1.8.0", | ||
| "version": "1.9.0", | ||
| "type": "module", | ||
@@ -20,4 +20,4 @@ "description": "CIP-0103 provider for web dApps, covering both Sync and Async APIs.", | ||
| "scripts": { | ||
| "build": "tsup --onSuccess \"tsc\"", | ||
| "dev": "tsup --watch --onSuccess \"tsc\"", | ||
| "build": "tsdown --onSuccess \"tsc\"", | ||
| "dev": "tsdown --watch --onSuccess \"tsc\"", | ||
| "flatpack": "yarn pack --out \"$FLATPACK_OUTDIR\"", | ||
@@ -29,16 +29,16 @@ "clean": "tsc -b --clean; rm -rf dist", | ||
| "devDependencies": { | ||
| "@vitest/browser-playwright": "^4.1.8", | ||
| "@vitest/coverage-v8": "^4.1.8", | ||
| "playwright": "^1.60.0", | ||
| "tsup": "^8.5.1", | ||
| "@vitest/browser-playwright": "^4.1.10", | ||
| "@vitest/coverage-v8": "^4.1.10", | ||
| "playwright": "^1.61.1", | ||
| "tsdown": "^0.22.9", | ||
| "typescript": "^5.9.3", | ||
| "vitest": "^4.1.8" | ||
| "vitest": "^4.1.10" | ||
| }, | ||
| "dependencies": { | ||
| "@canton-network/core-ledger-client-types": "^1.8.0", | ||
| "@canton-network/core-rpc-transport": "^1.8.0", | ||
| "@canton-network/core-splice-provider": "^1.8.0", | ||
| "@canton-network/core-types": "^1.8.0", | ||
| "@canton-network/core-wallet-dapp-remote-rpc-client": "^1.8.0", | ||
| "@canton-network/core-wallet-dapp-rpc-client": "^1.8.0" | ||
| "@canton-network/core-ledger-client-types": "^1.9.0", | ||
| "@canton-network/core-rpc-transport": "^1.9.0", | ||
| "@canton-network/core-splice-provider": "^1.9.0", | ||
| "@canton-network/core-types": "^1.9.0", | ||
| "@canton-network/core-wallet-dapp-remote-rpc-client": "^1.9.0", | ||
| "@canton-network/core-wallet-dapp-rpc-client": "^1.9.0" | ||
| }, | ||
@@ -45,0 +45,0 @@ "files": [ |
+146
-2
@@ -1,3 +0,147 @@ | ||
| # provider-dapp | ||
| # @canton-network/core-provider-dapp | ||
| This package supplies a CIP-0103 implementation of a Provider for Canton dApps. | ||
| [CIP-103](https://github.com/canton-foundation/cips/blob/main/cip-0103/cip-0103.md) | ||
| **Provider** implementations for Canton dApps. Extends | ||
| [`@canton-network/core-splice-provider`](../splice-provider) with wallet-mediated access to | ||
| the dApp API (and proxied ledger calls). | ||
| Most applications should use | ||
| [`@canton-network/dapp-sdk`](https://www.npmjs.com/package/@canton-network/dapp-sdk), which | ||
| picks and wraps these providers. Use this package directly when building lower-level | ||
| integrations or custom discovery / transport wiring. | ||
| Published on [npm](https://www.npmjs.com/package/@canton-network/core-provider-dapp) under | ||
| Apache-2.0. | ||
| ## Install | ||
| ```bash | ||
| npm install @canton-network/core-provider-dapp | ||
| ``` | ||
| ## Providers | ||
| | Class | API | Typical wallet | Transport | | ||
| | ------------------- | ------------- | --------------------------- | --------------------------------- | | ||
| | `DappSyncProvider` | CIP-103 Sync | Browser extension / desktop | `postMessage` (`WindowTransport`) | | ||
| | `DappAsyncProvider` | CIP-103 Async | Remote / custody gateway | HTTPS RPC + SSE | | ||
| ```mermaid | ||
| flowchart LR | ||
| dApp["dApp / dApp SDK"] --> Sync["DappSyncProvider"] | ||
| dApp --> Async["DappAsyncProvider"] | ||
| Sync -->|"postMessage"| Ext["Extension / desktop wallet"] | ||
| Async -->|"HTTPS + SSE"| Gw["Remote wallet gateway"] | ||
| Ext --> LAPI["JSON Ledger API"] | ||
| Gw --> LAPI | ||
| ``` | ||
| Both implement the same Provider surface (`request`, `on`, `emit`, `removeListener`). Method | ||
| and event types come from the generated OpenRPC clients | ||
| (`@canton-network/core-wallet-dapp-rpc-client` and | ||
| `@canton-network/core-wallet-dapp-remote-rpc-client`). | ||
| ## Sync vs Async | ||
| **Sync** — user interaction is in-process (popup / extension). Methods return results | ||
| directly. | ||
| **Async** — user interaction cannot block. Methods that need approval return a `userUrl` | ||
| (or similar) for the user to complete the action; the outcome arrives later as an event | ||
| (for example `connected`, `txChanged`, `messageSignature`). | ||
| | | Sync | Async | | ||
| | ---------------- | -------------------------------------------- | ------------------------------------------------ | | ||
| | Connect | Returns session when ready | May return `userUrl`; `connected` after login | | ||
| | `prepareExecute` | Completes in the request | Returns `userUrl`; progress via `txChanged` | | ||
| | `signMessage` | Returns signature | Pending / signed / failed via `messageSignature` | | ||
| | Events | Wallet notifications on the window transport | Shared SSE stream from the gateway | | ||
| ## Usage | ||
| ### `DappSyncProvider` | ||
| Defaults to a `WindowTransport` bound to `window`. Pass a custom `RpcTransport` when testing | ||
| or bridging a non-browser host. | ||
| ```ts | ||
| import { DappSyncProvider } from '@canton-network/core-provider-dapp' | ||
| const provider = new DappSyncProvider() | ||
| provider.on('statusChanged', (status) => { | ||
| console.log('connected:', status.connection.isConnected) | ||
| }) | ||
| const { isConnected } = await provider.request({ method: 'isConnected' }) | ||
| if (!isConnected) { | ||
| await provider.request({ method: 'connect' }) | ||
| } | ||
| const accounts = await provider.request({ method: 'listAccounts' }) | ||
| ``` | ||
| ### `DappAsyncProvider` | ||
| Point at the remote gateway base URL. An optional session token opens the SSE event stream | ||
| immediately; after IDP auth in a popup, the provider updates the token and reconnects SSE. | ||
| ```ts | ||
| import { DappAsyncProvider } from '@canton-network/core-provider-dapp' | ||
| const provider = new DappAsyncProvider('https://wallet-gateway.example.com') | ||
| provider.on('connected', (status) => { | ||
| console.log('session ready', status) | ||
| }) | ||
| provider.on('txChanged', (tx) => { | ||
| if (tx.status === 'executed') console.log(tx.payload.updateId) | ||
| }) | ||
| const connect = await provider.request({ method: 'connect' }) | ||
| // If not already authenticated, open connect.userUrl for the user to log in. | ||
| ``` | ||
| ## Events | ||
| Subscribe with `provider.on` / `provider.removeListener`. Payloads follow CIP-103 / the | ||
| OpenRPC event schemas. | ||
| | Event | Sync | Async | When | | ||
| | ------------------ | ---- | ----- | ---------------------------------------- | | ||
| | `statusChanged` | yes | yes | Connection / session changes | | ||
| | `accountsChanged` | yes | yes | Parties added/removed or primary changes | | ||
| | `txChanged` | yes | yes | `prepareExecute` lifecycle | | ||
| | `connected` | — | yes | Login completed after async `connect` | | ||
| | `messageSignature` | — | yes | Async `signMessage` lifecycle | | ||
| `DappSyncProvider` bridges wallet-pushed notifications from `WindowTransport` into the | ||
| provider listener map. `DappAsyncProvider` multiplexes a shared `EventSource` across | ||
| instances for the same gateway URL + token. | ||
| ## `window.canton` | ||
| This package augments `Window` with an optional injected provider: | ||
| ```ts | ||
| window.canton?: Provider<DappLedgerRpc> | ||
| ``` | ||
| `DappLedgerRpc` is the Sync dApp RPC map combined with Ledger `ledgerApi` operation types, | ||
| matching a full browser wallet injection that can both speak CIP-103 and proxy ledger calls. | ||
| ## Related | ||
| | Package | Role | | ||
| | ------------------------------------------------------------ | ----------------------------------------- | | ||
| | [`@canton-network/core-splice-provider`](../splice-provider) | Provider interface and `AbstractProvider` | | ||
| | [`@canton-network/core-provider-ledger`](../provider-ledger) | Direct JSON LAPI provider (no wallet) | | ||
| | [`@canton-network/core-rpc-transport`](../rpc-transport) | `WindowTransport`, `HttpTransport`, … | | ||
| | [`@canton-network/dapp-sdk`](../../sdk/dapp-sdk) | High-level SDK on top of these providers | | ||
| ## Specs | ||
| - Sync OpenRPC: [`openrpc-dapp-api.json`](../../api-specs/openrpc-dapp-api.json) | ||
| - Async OpenRPC: [`openrpc-dapp-remote-api.json`](../../api-specs/openrpc-dapp-remote-api.json) | ||
| - [CIP-103](https://github.com/canton-foundation/cips/blob/main/cip-0103/cip-0103.md) |
Major refactor
Supply chain riskPackage has recently undergone a major refactor. It may be unstable or indicate significant internal changes. Use caution when updating to versions that include significant changes.
45077
13.01%358
16.61%148
3600%1
Infinity%