diff --git a/.changeset/kind-fans-jog.md b/.changeset/kind-fans-jog.md new file mode 100644 index 0000000..9408a19 --- /dev/null +++ b/.changeset/kind-fans-jog.md @@ -0,0 +1,5 @@ +--- +'@fedimint/core-web': patch +--- + +Added Example projects to docs containing Stackblitz previews diff --git a/.github/workflows/deploy-preview.yml b/.github/workflows/deploy-preview.yml index f25baf4..d879cbd 100644 --- a/.github/workflows/deploy-preview.yml +++ b/.github/workflows/deploy-preview.yml @@ -1,3 +1,4 @@ +# NO LONGER USED - the docs site is now being deployed to github pages instead of the example name: Deploy Vite-Core Example to GitHub Pages on: diff --git a/docs/.vitepress/config.ts b/docs/.vitepress/config.ts index 5e6239e..11cf78b 100644 --- a/docs/.vitepress/config.ts +++ b/docs/.vitepress/config.ts @@ -49,7 +49,7 @@ export default withMermaid({ }, nav: [ { text: 'Documentation', link: '/core/getting-started' }, - { text: 'Examples', link: '/examples' }, + { text: 'Examples', link: '/examples/vite-react' }, { text: 'More', items: [ diff --git a/docs/.vitepress/sidebar.ts b/docs/.vitepress/sidebar.ts index 9d4b135..ecb1911 100644 --- a/docs/.vitepress/sidebar.ts +++ b/docs/.vitepress/sidebar.ts @@ -22,6 +22,16 @@ export function getSidebar() { ], }, ], + '/examples/': [ + { + base: '/examples/', + text: 'Examples', + items: [ + { text: 'Vite + React', link: 'vite-react' }, + { text: 'Vanilla JS', link: 'bare-js' }, + ], + }, + ], } satisfies DefaultTheme.Sidebar } diff --git a/docs/core/FedimintWallet/constructor.md b/docs/core/FedimintWallet/constructor.md index 9328369..124697a 100644 --- a/docs/core/FedimintWallet/constructor.md +++ b/docs/core/FedimintWallet/constructor.md @@ -1,4 +1,4 @@ -# FedimintWallet +# new FedimintWallet()t Creates a new instance of FedimintWallet. @@ -39,15 +39,13 @@ until needed. Default is false. import { FedimintWallet } from '@fedimint/core-web' // Create a wallet with immediate initialization -const wallet = new FedimintWallet() +const wallet = new FedimintWallet() // wasm gets initialized here wallet.open() // Create a wallet with lazy initialization -const lazyWallet = new FedimintWallet(true) +const lazyWallet = new FedimintWallet(true) // lazy = true // Some time later... -lazyWallet.initialize().then(() => { - lazyWallet.open() -}) +lazyWallet.open() // wasm gets initialized here ``` #### Defined in diff --git a/docs/core/FedimintWallet/index.md b/docs/core/FedimintWallet/index.md index 73d5b42..30e72e0 100644 --- a/docs/core/FedimintWallet/index.md +++ b/docs/core/FedimintWallet/index.md @@ -1,4 +1,4 @@ -# Wallet Overview +# FedimintWallet Overview The `FedimintWallet` class serves as the main entry point for the library. It orchestrates the various services and the WorkerClient. diff --git a/docs/core/getting-started.md b/docs/core/getting-started.md index e6a61c7..ac45d72 100644 --- a/docs/core/getting-started.md +++ b/docs/core/getting-started.md @@ -87,6 +87,8 @@ Currently requires modifying the library and utilizing the `@fedimint/wasm-web` See the [bare-js sample app](https://github.com/fedimint/fedimint-web-sdk/tree/main/examples/bare-js) for a full working example. +::: + ### Webpack ::: details Webpack Setup @@ -187,12 +189,6 @@ Check out the Vite + React example in the [`examples/vite-core`](https://github. For a list of public federations with invite codes, visit [Bitcoin Mints](https://bitcoinmints.com/?tab=mints&showFedimint=true). -## Next Steps - -- **API Reference**: Browse the collection of available methods and learn how to use them. -- **Advanced Usage**: Discover more complex scenarios and best practices for using @fedimint/core-web. -- **Framework Integration**: Learn how to integrate @fedimint/core-web with popular front-end frameworks. - ## What's Next? - To see the sdk in action, check out the [examples](../examples/index.md) diff --git a/docs/examples/bare-js.md b/docs/examples/bare-js.md new file mode 100644 index 0000000..0b4d640 --- /dev/null +++ b/docs/examples/bare-js.md @@ -0,0 +1,23 @@ +# Bare JS Example + +This example shows how to use the `core-web` package in a bare javascript environment (no bundler). + +There's no ui, so open your browser's console to see the library in action. + +## Live Preview + + + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/fedimint/fedimint-web-sdk/tree/main/examples/bare-js) + +## Running the Example Locally + +```bash +# from the root of the repo + +# install dependencies +pnpm i + +# run the dev server +pnpm run dev:bare +``` diff --git a/docs/examples/index.md b/docs/examples/index.md deleted file mode 100644 index e69de29..0000000 diff --git a/docs/examples/vite-react.md b/docs/examples/vite-react.md new file mode 100644 index 0000000..7c5c496 --- /dev/null +++ b/docs/examples/vite-react.md @@ -0,0 +1,21 @@ +# Vite + React Example + +This is an example application demonstrating the usage of Fedimint client in React Application application. + +## Live Preview + + + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/fedimint/fedimint-web-sdk/tree/main/examples/vite-core) + +## Running the Example Locally + +```bash +# from the root of the repo + +# install dependencies +pnpm i + +# run the dev server +pnpm run dev:vite +``` diff --git a/examples/bare-js/README.md b/examples/bare-js/README.md index f2377d9..0b4d640 100644 --- a/examples/bare-js/README.md +++ b/examples/bare-js/README.md @@ -2,11 +2,22 @@ This example shows how to use the `core-web` package in a bare javascript environment (no bundler). -## Running the example +There's no ui, so open your browser's console to see the library in action. + +## Live Preview + + + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/fedimint/fedimint-web-sdk/tree/main/examples/bare-js) + +## Running the Example Locally ```bash # from the root of the repo + +# install dependencies +pnpm i + +# run the dev server pnpm run dev:bare ``` - -There's no ui, so open your browser's console to see the library in action. \ No newline at end of file diff --git a/examples/bare-js/index.html b/examples/bare-js/index.html index 994b36e..e18a6b4 100644 --- a/examples/bare-js/index.html +++ b/examples/bare-js/index.html @@ -2,19 +2,58 @@ + Testy Fedimint Web SDK Bare + +
+

Fedimint Web SDK Bare html/js example

+
+ + +
+

Console output:

+
+

Faucet Link: https://faucet.mutinynet.com/

+
- \ No newline at end of file diff --git a/examples/bare-js/index.js b/examples/bare-js/index.js index b66f8f9..264bf1e 100644 --- a/examples/bare-js/index.js +++ b/examples/bare-js/index.js @@ -1,2 +1,2 @@ -const e = ["debug", "info", "warn", "error", "none"]; const t = new class { constructor(e = "none") { this.level = e } setLevel(e) { this.level = e } coerceLevel(t) { return e.includes(t.toLocaleUpperCase()) ? t.toLocaleUpperCase() : "info" } log(e, t, ...i) { const n = this.coerceLevel(e); if (!this.shouldLog(n)) return; (0, console[n])(`[${n.toUpperCase()}] ${t}`, ...i) } debug(e, ...t) { this.log("debug", e, ...t) } info(e, ...t) { this.log("info", e, ...t) } warn(e, ...t) { this.log("warn", e, ...t) } error(e, ...t) { this.log("error", e, ...t) } shouldLog(e) { const t = ["debug", "info", "warn", "error", "none"], i = t.indexOf(e); return t.indexOf(this.level) <= i && "none" !== this.level && "none" !== e } }; class i { constructor() { this.requestCounter = 0, this.requestCallbacks = new Map, this.initPromise = null, this.worker = new Worker(new URL("./worker.js", import.meta.url), { type: "module" }), this.worker.onmessage = this.handleWorkerMessage.bind(this), this.worker.onerror = this.handleWorkerError.bind(this), t.info("WorkerClient instantiated"), t.debug("WorkerClient", this.worker) } initialize() { return this.initPromise || (this.initPromise = this.sendSingleMessage("init")), this.initPromise } handleWorkerLogs(e) { const { type: i, level: n, message: s, ...r } = e.data; t.log(n, s, ...r) } handleWorkerError(e) { t.error("Worker error", e) } handleWorkerMessage(e) { const { type: i, requestId: n, ...s } = e.data; "log" === i && this.handleWorkerLogs(e.data); const r = this.requestCallbacks.get(n); t.debug("WorkerClient - handleWorkerMessage", e.data), r ? r(s) : t.warn("WorkerClient - handleWorkerMessage - received message with no callback", n, e.data) } sendSingleMessage(e, i) { return new Promise(((n, s) => { const r = ++this.requestCounter; t.debug("WorkerClient - sendSingleMessage", r, e, i), this.requestCallbacks.set(r, (e => { this.requestCallbacks.delete(r), t.debug("WorkerClient - sendSingleMessage - response", r, e), e.data ? n(e.data) : e.error ? s(e.error) : t.warn("WorkerClient - sendSingleMessage - malformed response", r, e) })), this.worker.postMessage({ type: e, payload: i, requestId: r }) })) } rpcStream(e, i, n, s, r, a = () => { }) { const o = ++this.requestCounter; t.debug("WorkerClient - rpcStream", o, e, i, n); let l = () => { }, c = !1; const h = new Promise((e => { l = () => { c ? e() : setTimeout((() => l()), 0) } })); return this._rpcStreamInner(o, e, i, n, s, r, a, h).then((() => { c = !0 })), l } async _rpcStreamInner(e, t, i, n, s, r, a = () => { }, o) { this.requestCallbacks.set(e, (t => { void 0 !== t.error ? r(t.error) : void 0 !== t.data ? s(t.data) : void 0 !== t.end && (this.requestCallbacks.delete(e), a()) })), this.worker.postMessage({ type: "rpc", payload: { module: t, method: i, body: n }, requestId: e }), o.then((() => { this.worker?.postMessage({ type: "unsubscribe", requestId: e }), this.requestCallbacks.delete(e) })) } rpcSingle(e, i, n) { return t.debug("WorkerClient - rpcSingle", e, i, n), new Promise(((t, s) => { this.rpcStream(e, i, n, t, s) })) } cleanup() { this.worker.terminate(), this.initPromise = null, this.requestCallbacks.clear() } } class n { constructor(e) { this.client = e } async redeemEcash(e) { await this.client.rpcSingle("mint", "reissue_external_notes", { oob_notes: e, extra_meta: null }) } async reissueExternalNotes(e, t) { return await this.client.rpcSingle("mint", "reissue_external_notes", { oob_notes: e, extra_meta: t }) } subscribeReissueExternalNotes(e, t = () => { }, i = () => { }) { return this.client.rpcStream("mint", "subscribe_reissue_external_notes", { operation_id: e }, t, i) } async spendNotes(e, t, i, n) { return await this.client.rpcSingle("mint", "spend_notes", { min_amount: e, try_cancel_after: t, include_invite: i, extra_meta: n }) } async validateNotes(e) { return await this.client.rpcSingle("mint", "validate_notes", { oob_notes: e }) } async tryCancelSpendNotes(e) { await this.client.rpcSingle("mint", "try_cancel_spend_notes", { operation_id: e }) } subscribeSpendNotes(e, t = () => { }, i = () => { }) { return this.client.rpcStream("mint", "subscribe_spend_notes", { operation_id: e }, (e => t(e)), i) } async awaitSpendOobRefund(e) { return await this.client.rpcSingle("mint", "await_spend_oob_refund", { operation_id: e }) } } class s { constructor(e) { this.client = e } async getBalance() { return await this.client.rpcSingle("", "get_balance", {}) } subscribeBalance(e = () => { }, t = () => { }) { return this.client.rpcStream("", "subscribe_balance_changes", {}, (t => e(parseInt(t))), t) } } class r { constructor(e) { this.client = e } async createBolt11InvoiceWithGateway(e, t, i = null, n = {}, s) { return await this.client.rpcSingle("ln", "create_bolt11_invoice", { amount: e, description: t, expiry_time: i, extra_meta: n, gateway: s }) } async createBolt11Invoice(e, t, i = null, n = {}) { await this.updateGatewayCache(); const s = await this._getDefaultGatewayInfo(); return await this.client.rpcSingle("ln", "create_bolt11_invoice", { amount: e, description: t, expiry_time: i, extra_meta: n, gateway: s.info }) } async payBolt11InvoiceWithGateway(e, t, i = {}) { return await this.client.rpcSingle("ln", "pay_bolt11_invoice", { maybe_gateway: t, invoice: e, extra_meta: i }) } async _getDefaultGatewayInfo() { return (await this.listGateways())[0] } async payBolt11Invoice(e, t = {}) { await this.updateGatewayCache(); const i = await this._getDefaultGatewayInfo(); return await this.client.rpcSingle("ln", "pay_bolt11_invoice", { maybe_gateway: i.info, invoice: e, extra_meta: t }) } subscribeLnPay(e, t = () => { }, i = () => { }) { return this.client.rpcStream("ln", "subscribe_ln_pay", { operation_id: e }, t, i) } subscribeLnReceive(e, t = () => { }, i = () => { }) { return this.client.rpcStream("ln", "subscribe_ln_receive", { operation_id: e }, t, i) } async getGateway(e = null, t = !1) { return await this.client.rpcSingle("ln", "get_gateway", { gateway_id: e, force_internal: t }) } async listGateways() { return await this.client.rpcSingle("ln", "list_gateways", {}) } async updateGatewayCache() { return await this.client.rpcSingle("ln", "update_gateway_cache", {}) } } class a { constructor(e) { this.client = e } async hasPendingRecoveries() { return await this.client.rpcSingle("", "has_pending_recoveries", {}) } async waitForAllRecoveries() { await this.client.rpcSingle("", "wait_for_all_recoveries", {}) } subscribeToRecoveryProgress(e, t) { return this.client.rpcStream("", "subscribe_to_recovery_progress", {}, e, t) } } class o { constructor(e) { this.client = e } async getConfig() { return await this.client.rpcSingle("", "get_config", {}) } async getFederationId() { return await this.client.rpcSingle("", "get_federation_id", {}) } async getInviteCode(e) { return await this.client.rpcSingle("", "get_invite_code", { peer: e }) } async joinFederation(e, t) { if (!(await this.client.sendSingleMessage("join", { inviteCode: e, clientName: t })).success) throw new Error("Failed to join federation") } async listOperations() { return await this.client.rpcSingle("", "list_operations", {}) } } const l = "fm-default"; class c { constructor(e = !1) { this.openPromise = null, this.resolveOpen = () => { }, this._isOpen = !1, this.openPromise = new Promise((e => { this.resolveOpen = e })), this.client = new i, this.mint = new n(this.client), this.lightning = new r(this.client), this.balance = new s(this.client), this.federation = new o(this.client), this.recovery = new a(this.client), t.info("FedimintWallet instantiated"), e || this.initialize() } async initialize() { t.info("Initializing WorkerClient"), await this.client.initialize(), t.info("WorkerClient initialized") } async waitForOpen() { return this._isOpen ? Promise.resolve() : this.openPromise } async open(e = l) { if (await this.client.initialize(), this._isOpen) throw new Error("The FedimintWallet is already open."); const { success: t } = await this.client.sendSingleMessage("open", { clientName: e }); return t && (this._isOpen = !!t, this.resolveOpen()), t } async joinFederation(e, t = l) { if (await this.client.initialize(), this._isOpen) throw new Error("The FedimintWallet is already open. You can only call `joinFederation` on closed clients."); (await this.client.sendSingleMessage("join", { inviteCode: e, clientName: t })).success && (this._isOpen = !0, this.resolveOpen()) } async cleanup() { this.openPromise = null, this._isOpen = !1, this.client.cleanup() } isOpen() { return this._isOpen } setLogLevel(e) { t.setLevel(e), t.info(`Log level set to ${e}.`) } } export { c as FedimintWallet }; +const e=["debug","info","warn","error","none"];const t=new class{constructor(e="none"){this.level=e}setLevel(e){this.level=e}coerceLevel(t){return e.includes(t.toLocaleUpperCase())?t.toLocaleUpperCase():"info"}log(e,t,...i){const n=this.coerceLevel(e);if(!this.shouldLog(n))return;(0,console[n])(`[${n.toUpperCase()}] ${t}`,...i)}debug(e,...t){this.log("debug",e,...t)}info(e,...t){this.log("info",e,...t)}warn(e,...t){this.log("warn",e,...t)}error(e,...t){this.log("error",e,...t)}shouldLog(e){const t=["debug","info","warn","error","none"],i=t.indexOf(e);return t.indexOf(this.level)<=i&&"none"!==this.level&&"none"!==e}};class i{constructor(){this.requestCounter=0,this.requestCallbacks=new Map,this.initPromise=null,this.worker=new Worker(new URL("./worker.js",import.meta.url),{type:"module"}),this.worker.onmessage=this.handleWorkerMessage.bind(this),this.worker.onerror=this.handleWorkerError.bind(this),t.info("WorkerClient instantiated"),t.debug("WorkerClient",this.worker)}initialize(){return this.initPromise||(this.initPromise=this.sendSingleMessage("init")),this.initPromise}handleWorkerLogs(e){const{type:i,level:n,message:s,...r}=e.data;t.log(n,s,...r)}handleWorkerError(e){t.error("Worker error",e)}handleWorkerMessage(e){const{type:i,requestId:n,...s}=e.data;"log"===i&&this.handleWorkerLogs(e.data);const r=this.requestCallbacks.get(n);t.debug("WorkerClient - handleWorkerMessage",e.data),r?r(s):t.warn("WorkerClient - handleWorkerMessage - received message with no callback",n,e.data)}sendSingleMessage(e,i){return new Promise(((n,s)=>{const r=++this.requestCounter;t.debug("WorkerClient - sendSingleMessage",r,e,i),this.requestCallbacks.set(r,(e=>{this.requestCallbacks.delete(r),t.debug("WorkerClient - sendSingleMessage - response",r,e),e.data?n(e.data):e.error?s(e.error):t.warn("WorkerClient - sendSingleMessage - malformed response",r,e)})),this.worker.postMessage({type:e,payload:i,requestId:r})}))}rpcStream(e,i,n,s,r,a=()=>{}){const o=++this.requestCounter;t.debug("WorkerClient - rpcStream",o,e,i,n);let l=()=>{},c=!1;const h=new Promise((e=>{l=()=>{c?e():setTimeout((()=>l()),0)}}));return this._rpcStreamInner(o,e,i,n,s,r,a,h).then((()=>{c=!0})),l}async _rpcStreamInner(e,t,i,n,s,r,a=()=>{},o){this.requestCallbacks.set(e,(t=>{void 0!==t.error?r(t.error):void 0!==t.data?s(t.data):void 0!==t.end&&(this.requestCallbacks.delete(e),a())})),this.worker.postMessage({type:"rpc",payload:{module:t,method:i,body:n},requestId:e}),o.then((()=>{this.worker?.postMessage({type:"unsubscribe",requestId:e}),this.requestCallbacks.delete(e)}))}rpcSingle(e,i,n){return t.debug("WorkerClient - rpcSingle",e,i,n),new Promise(((t,s)=>{this.rpcStream(e,i,n,t,s)}))}cleanup(){this.worker.terminate(),this.initPromise=null,this.requestCallbacks.clear()}_getRequestCounter(){return this.requestCounter}_getRequestCallbackMap(){return this.requestCallbacks}}class n{constructor(e){this.client=e}async redeemEcash(e){await this.client.rpcSingle("mint","reissue_external_notes",{oob_notes:e,extra_meta:null})}async reissueExternalNotes(e,t){return await this.client.rpcSingle("mint","reissue_external_notes",{oob_notes:e,extra_meta:t})}subscribeReissueExternalNotes(e,t=()=>{},i=()=>{}){return this.client.rpcStream("mint","subscribe_reissue_external_notes",{operation_id:e},t,i)}async spendNotes(e,t,i,n){return await this.client.rpcSingle("mint","spend_notes",{min_amount:e,try_cancel_after:t,include_invite:i,extra_meta:n})}async validateNotes(e){return await this.client.rpcSingle("mint","validate_notes",{oob_notes:e})}async tryCancelSpendNotes(e){await this.client.rpcSingle("mint","try_cancel_spend_notes",{operation_id:e})}subscribeSpendNotes(e,t=()=>{},i=()=>{}){return this.client.rpcStream("mint","subscribe_spend_notes",{operation_id:e},(e=>t(e)),i)}async awaitSpendOobRefund(e){return await this.client.rpcSingle("mint","await_spend_oob_refund",{operation_id:e})}}class s{constructor(e){this.client=e}async getBalance(){return await this.client.rpcSingle("","get_balance",{})}subscribeBalance(e=()=>{},t=()=>{}){return this.client.rpcStream("","subscribe_balance_changes",{},(t=>e(parseInt(t))),t)}}class r{constructor(e){this.client=e}async createInvoiceWithGateway(e,t,i=null,n={},s){return await this.client.rpcSingle("ln","create_bolt11_invoice",{amount:e,description:t,expiry_time:i,extra_meta:n,gateway:s})}async createInvoice(e,t,i=null,n={}){await this.updateGatewayCache();const s=await this._getDefaultGatewayInfo();return await this.client.rpcSingle("ln","create_bolt11_invoice",{amount:e,description:t,expiry_time:i,extra_meta:n,gateway:s.info})}async payInvoiceWithGateway(e,t,i={}){return await this.client.rpcSingle("ln","pay_bolt11_invoice",{maybe_gateway:t,invoice:e,extra_meta:i})}async _getDefaultGatewayInfo(){return(await this.listGateways())[0]}async payInvoice(e,t={}){await this.updateGatewayCache();const i=await this._getDefaultGatewayInfo();return await this.client.rpcSingle("ln","pay_bolt11_invoice",{maybe_gateway:i.info,invoice:e,extra_meta:t})}subscribeLnPay(e,t=()=>{},i=()=>{}){return this.client.rpcStream("ln","subscribe_ln_pay",{operation_id:e},t,i)}subscribeLnReceive(e,t=()=>{},i=()=>{}){return this.client.rpcStream("ln","subscribe_ln_receive",{operation_id:e},t,i)}async getGateway(e=null,t=!1){return await this.client.rpcSingle("ln","get_gateway",{gateway_id:e,force_internal:t})}async listGateways(){return await this.client.rpcSingle("ln","list_gateways",{})}async updateGatewayCache(){return await this.client.rpcSingle("ln","update_gateway_cache",{})}}class a{constructor(e){this.client=e}async hasPendingRecoveries(){return await this.client.rpcSingle("","has_pending_recoveries",{})}async waitForAllRecoveries(){await this.client.rpcSingle("","wait_for_all_recoveries",{})}subscribeToRecoveryProgress(e,t){return this.client.rpcStream("","subscribe_to_recovery_progress",{},e,t)}}class o{constructor(e){this.client=e}async getConfig(){return await this.client.rpcSingle("","get_config",{})}async getFederationId(){return await this.client.rpcSingle("","get_federation_id",{})}async getInviteCode(e){return await this.client.rpcSingle("","get_invite_code",{peer:e})}async listOperations(){return await this.client.rpcSingle("","list_operations",{})}}const l="fm-default";class c{constructor(e=!1){this._openPromise=null,this._resolveOpen=()=>{},this._isOpen=!1,this._openPromise=new Promise((e=>{this._resolveOpen=e})),this._client=new i,this.mint=new n(this._client),this.lightning=new r(this._client),this.balance=new s(this._client),this.federation=new o(this._client),this.recovery=new a(this._client),t.info("FedimintWallet instantiated"),e||this.initialize()}async initialize(){t.info("Initializing WorkerClient"),await this._client.initialize(),t.info("WorkerClient initialized")}async waitForOpen(){return this._isOpen?Promise.resolve():this._openPromise}async open(e=l){if(await this._client.initialize(),this._isOpen)throw new Error("The FedimintWallet is already open.");const{success:t}=await this._client.sendSingleMessage("open",{clientName:e});return t&&(this._isOpen=!!t,this._resolveOpen()),t}async joinFederation(e,t=l){if(await this._client.initialize(),this._isOpen)throw new Error("The FedimintWallet is already open. You can only call `joinFederation` on closed clients.");(await this._client.sendSingleMessage("join",{inviteCode:e,clientName:t})).success&&(this._isOpen=!0,this._resolveOpen())}async cleanup(){this._openPromise=null,this._isOpen=!1,this._client.cleanup()}isOpen(){return this._isOpen}setLogLevel(e){t.setLevel(e),t.info(`Log level set to ${e}.`)}}export{c as FedimintWallet}; //# sourceMappingURL=index.js.map diff --git a/examples/bare-js/package-lock.json b/examples/bare-js/package-lock.json deleted file mode 100644 index e3fc177..0000000 --- a/examples/bare-js/package-lock.json +++ /dev/null @@ -1,613 +0,0 @@ -{ - "name": "testy-bare", - "version": "1.0.0", - "lockfileVersion": 3, - "requires": true, - "packages": { - "": { - "name": "testy-bare", - "version": "1.0.0", - "license": "ISC", - "dependencies": { - "@fedimint/core-web": "^0.0.0-canary-20240923175317" - }, - "devDependencies": { - "http-server": "^14.1.1" - } - }, - "node_modules/@fedimint/core-web": { - "version": "0.0.0-canary-20240923175317", - "resolved": "https://registry.npmjs.org/@fedimint/core-web/-/core-web-0.0.0-canary-20240923175317.tgz", - "integrity": "sha512-tsGukctyGBcFnQUrMqt1Pp5ce2aXkfNigD9yyh+wvlAOEwliowaJeVFF75KBjnf67vniRi48lTR8Q5R+R7R+og==", - "bundleDependencies": [ - "@fedimint/fedimint-client-wasm" - ], - "dependencies": { - "@fedimint/fedimint-client-wasm": "file:./wasm" - } - }, - "node_modules/ansi-styles": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", - "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-convert": "^2.0.1" - }, - "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" - } - }, - "node_modules/async": { - "version": "2.6.4", - "resolved": "https://registry.npmjs.org/async/-/async-2.6.4.tgz", - "integrity": "sha512-mzo5dfJYwAn29PeiJ0zvwTo04zj8HDJj0Mn8TD7sno7q12prdbnasKJHhkm2c1LgrhlJ0teaea8860oxi51mGA==", - "dev": true, - "license": "MIT", - "dependencies": { - "lodash": "^4.17.14" - } - }, - "node_modules/basic-auth": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", - "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", - "dev": true, - "license": "MIT", - "dependencies": { - "safe-buffer": "5.1.2" - }, - "engines": { - "node": ">= 0.8" - } - }, - "node_modules/call-bind": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.7.tgz", - "integrity": "sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "set-function-length": "^1.2.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/chalk": { - "version": "4.1.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", - "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", - "dev": true, - "license": "MIT", - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, - "engines": { - "node": ">=10" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/color-convert": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", - "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "color-name": "~1.1.4" - }, - "engines": { - "node": ">=7.0.0" - } - }, - "node_modules/color-name": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", - "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", - "dev": true, - "license": "MIT" - }, - "node_modules/corser": { - "version": "2.0.1", - "resolved": "https://registry.npmjs.org/corser/-/corser-2.0.1.tgz", - "integrity": "sha512-utCYNzRSQIZNPIcGZdQc92UVJYAhtGAteCFg0yRaFm8f0P+CPtyGyHXJcGXnffjCybUCEx3FQ2G7U3/o9eIkVQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4.0" - } - }, - "node_modules/debug": { - "version": "3.2.7", - "resolved": "https://registry.npmjs.org/debug/-/debug-3.2.7.tgz", - "integrity": "sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "ms": "^2.1.1" - } - }, - "node_modules/define-data-property": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/define-data-property/-/define-data-property-1.1.4.tgz", - "integrity": "sha512-rBMvIzlpA8v6E+SJZoo++HAYqsLrkg7MSfIinMPFhmkorw7X+dOXVJQs+QT69zGkzMyfDnIMN2Wid1+NbL3T+A==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0", - "es-errors": "^1.3.0", - "gopd": "^1.0.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/es-define-property": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/es-define-property/-/es-define-property-1.0.0.tgz", - "integrity": "sha512-jxayLKShrEqqzJ0eumQbVhTYQM27CfT1T35+gCgDFoL82JLsXqTJ76zv6A0YLOgEnLUMvLzsDsGIrl8NFpT2gQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.2.4" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/es-errors": { - "version": "1.3.0", - "resolved": "https://registry.npmjs.org/es-errors/-/es-errors-1.3.0.tgz", - "integrity": "sha512-Zf5H2Kxt2xjTvbJvP2ZWLEICxA6j+hAmMzIlypy4xcBg1vKVnx89Wy0GbS+kf5cwCVFFzdCFh2XSCFNULS6csw==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/eventemitter3": { - "version": "4.0.7", - "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-4.0.7.tgz", - "integrity": "sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==", - "dev": true, - "license": "MIT" - }, - "node_modules/follow-redirects": { - "version": "1.15.9", - "resolved": "https://registry.npmjs.org/follow-redirects/-/follow-redirects-1.15.9.tgz", - "integrity": "sha512-gew4GsXizNgdoRyqmyfMHyAmXsZDk6mHkSxZFCzW9gwlbtOW44CDtYavM+y+72qD/Vq2l550kMF52DT8fOLJqQ==", - "dev": true, - "funding": [ - { - "type": "individual", - "url": "https://github.com/sponsors/RubenVerborgh" - } - ], - "license": "MIT", - "engines": { - "node": ">=4.0" - }, - "peerDependenciesMeta": { - "debug": { - "optional": true - } - } - }, - "node_modules/function-bind": { - "version": "1.1.2", - "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.2.tgz", - "integrity": "sha512-7XHNxH7qX9xG5mIwxkhumTox/MIRNcOgDrxWsMt2pAr23WHp6MrRlN7FBSFpCpr+oVO0F744iUgR82nJMfG2SA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/get-intrinsic": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/get-intrinsic/-/get-intrinsic-1.2.4.tgz", - "integrity": "sha512-5uYhsJH8VJBTv7oslg4BznJYhDoRI6waYCxMmCdnTrcCrHA/fCFKoTFz2JKKE0HdDFUF7/oQuhzumXJK7paBRQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "has-proto": "^1.0.1", - "has-symbols": "^1.0.3", - "hasown": "^2.0.0" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/gopd": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/gopd/-/gopd-1.0.1.tgz", - "integrity": "sha512-d65bNlIadxvpb/A2abVdlqKqV563juRnZ1Wtk6s1sIR8uNsXR70xqIzVqxVf1eTqDunwT2MkczEeaezCKTZhwA==", - "dev": true, - "license": "MIT", - "dependencies": { - "get-intrinsic": "^1.1.3" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-flag": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", - "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">=8" - } - }, - "node_modules/has-property-descriptors": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/has-property-descriptors/-/has-property-descriptors-1.0.2.tgz", - "integrity": "sha512-55JNKuIW+vq4Ke1BjOTjM2YctQIvCT7GFzHwmfZPGo5wnrgkid0YQtnAleFSqumZm4az3n2BS+erby5ipJdgrg==", - "dev": true, - "license": "MIT", - "dependencies": { - "es-define-property": "^1.0.0" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-proto": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-proto/-/has-proto-1.0.3.tgz", - "integrity": "sha512-SJ1amZAJUiZS+PhsVLf5tGydlaVB8EdFpaSO4gmiUKUOxk8qzn5AIy4ZeJUmh22znIdk/uMAUT2pl3FxzVUH+Q==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/has-symbols": { - "version": "1.0.3", - "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.3.tgz", - "integrity": "sha512-l3LCuF6MgDNwTDKkdYGEihYjt5pRPbEg46rtlmnSPlUbgmB8LOIrKJbYYFBSbnPaJexMKtiPO8hmeRjRz2Td+A==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/hasown": { - "version": "2.0.2", - "resolved": "https://registry.npmjs.org/hasown/-/hasown-2.0.2.tgz", - "integrity": "sha512-0hJU9SCPvmMzIBdZFqNPXWa6dqh7WdH0cII9y+CyS8rG3nL48Bclra9HmKhVVUHyPWNH5Y7xDwAB7bfgSjkUMQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "function-bind": "^1.1.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/he": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/he/-/he-1.2.0.tgz", - "integrity": "sha512-F/1DnUGPopORZi0ni+CvrCgHQ5FyEAHRLSApuYWMmrbSwoN2Mn/7k+Gl38gJnR7yyDZk6WLXwiGod1JOWNDKGw==", - "dev": true, - "license": "MIT", - "bin": { - "he": "bin/he" - } - }, - "node_modules/html-encoding-sniffer": { - "version": "3.0.0", - "resolved": "https://registry.npmjs.org/html-encoding-sniffer/-/html-encoding-sniffer-3.0.0.tgz", - "integrity": "sha512-oWv4T4yJ52iKrufjnyZPkrN0CH3QnrUqdB6In1g5Fe1mia8GmF36gnfNySxoZtxD5+NmYw1EElVXiBk93UeskA==", - "dev": true, - "license": "MIT", - "dependencies": { - "whatwg-encoding": "^2.0.0" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/http-proxy": { - "version": "1.18.1", - "resolved": "https://registry.npmjs.org/http-proxy/-/http-proxy-1.18.1.tgz", - "integrity": "sha512-7mz/721AbnJwIVbnaSv1Cz3Am0ZLT/UBwkC92VlxhXv/k/BBQfM2fXElQNC27BVGr0uwUpplYPQM9LnaBMR5NQ==", - "dev": true, - "license": "MIT", - "dependencies": { - "eventemitter3": "^4.0.0", - "follow-redirects": "^1.0.0", - "requires-port": "^1.0.0" - }, - "engines": { - "node": ">=8.0.0" - } - }, - "node_modules/http-server": { - "version": "14.1.1", - "resolved": "https://registry.npmjs.org/http-server/-/http-server-14.1.1.tgz", - "integrity": "sha512-+cbxadF40UXd9T01zUHgA+rlo2Bg1Srer4+B4NwIHdaGxAGGv59nYRnGGDJ9LBk7alpS0US+J+bLLdQOOkJq4A==", - "dev": true, - "license": "MIT", - "dependencies": { - "basic-auth": "^2.0.1", - "chalk": "^4.1.2", - "corser": "^2.0.1", - "he": "^1.2.0", - "html-encoding-sniffer": "^3.0.0", - "http-proxy": "^1.18.1", - "mime": "^1.6.0", - "minimist": "^1.2.6", - "opener": "^1.5.1", - "portfinder": "^1.0.28", - "secure-compare": "3.0.1", - "union": "~0.5.0", - "url-join": "^4.0.1" - }, - "bin": { - "http-server": "bin/http-server" - }, - "engines": { - "node": ">=12" - } - }, - "node_modules/iconv-lite": { - "version": "0.6.3", - "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.6.3.tgz", - "integrity": "sha512-4fCk79wshMdzMp2rH06qWrJE4iolqLhCUH+OiuIgU++RB0+94NlDL81atO7GX55uUKueo0txHNtvEyI6D7WdMw==", - "dev": true, - "license": "MIT", - "dependencies": { - "safer-buffer": ">= 2.1.2 < 3.0.0" - }, - "engines": { - "node": ">=0.10.0" - } - }, - "node_modules/lodash": { - "version": "4.17.21", - "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.21.tgz", - "integrity": "sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==", - "dev": true, - "license": "MIT" - }, - "node_modules/mime": { - "version": "1.6.0", - "resolved": "https://registry.npmjs.org/mime/-/mime-1.6.0.tgz", - "integrity": "sha512-x0Vn8spI+wuJ1O6S7gnbaQg8Pxh4NNHb7KSINmEWKiPE4RKOplvijn+NkmYmmRgP68mc70j2EbeTFRsrswaQeg==", - "dev": true, - "license": "MIT", - "bin": { - "mime": "cli.js" - }, - "engines": { - "node": ">=4" - } - }, - "node_modules/minimist": { - "version": "1.2.8", - "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.8.tgz", - "integrity": "sha512-2yyAR8qBkN3YuheJanUpWC5U3bb5osDywNB8RzDVlDwDHbocAJveqqj1u8+SVD7jkWT4yvsHCpWqqWqAxb0zCA==", - "dev": true, - "license": "MIT", - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "license": "MIT", - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/ms": { - "version": "2.1.3", - "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.3.tgz", - "integrity": "sha512-6FlzubTLZG3J2a/NVCAleEhjzq5oxgHyaCU9yYXvcLsvoVaHJq/s5xXI6/XXP6tz7R9xAOtHnSO/tXtF3WRTlA==", - "dev": true, - "license": "MIT" - }, - "node_modules/object-inspect": { - "version": "1.13.2", - "resolved": "https://registry.npmjs.org/object-inspect/-/object-inspect-1.13.2.tgz", - "integrity": "sha512-IRZSRuzJiynemAXPYtPe5BoI/RESNYR7TYm50MC5Mqbd3Jmw5y790sErYw3V6SryFJD64b74qQQs9wn5Bg/k3g==", - "dev": true, - "license": "MIT", - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/opener": { - "version": "1.5.2", - "resolved": "https://registry.npmjs.org/opener/-/opener-1.5.2.tgz", - "integrity": "sha512-ur5UIdyw5Y7yEj9wLzhqXiy6GZ3Mwx0yGI+5sMn2r0N0v3cKJvUmFH5yPP+WXh9e0xfyzyJX95D8l088DNFj7A==", - "dev": true, - "license": "(WTFPL OR MIT)", - "bin": { - "opener": "bin/opener-bin.js" - } - }, - "node_modules/portfinder": { - "version": "1.0.32", - "resolved": "https://registry.npmjs.org/portfinder/-/portfinder-1.0.32.tgz", - "integrity": "sha512-on2ZJVVDXRADWE6jnQaX0ioEylzgBpQk8r55NE4wjXW1ZxO+BgDlY6DXwj20i0V8eB4SenDQ00WEaxfiIQPcxg==", - "dev": true, - "license": "MIT", - "dependencies": { - "async": "^2.6.4", - "debug": "^3.2.7", - "mkdirp": "^0.5.6" - }, - "engines": { - "node": ">= 0.12.0" - } - }, - "node_modules/qs": { - "version": "6.13.0", - "resolved": "https://registry.npmjs.org/qs/-/qs-6.13.0.tgz", - "integrity": "sha512-+38qI9SOr8tfZ4QmJNplMUxqjbe7LKvvZgWdExBOmd+egZTtjLB67Gu0HRX3u/XOq7UU2Nx6nsjvS16Z9uwfpg==", - "dev": true, - "license": "BSD-3-Clause", - "dependencies": { - "side-channel": "^1.0.6" - }, - "engines": { - "node": ">=0.6" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/requires-port": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz", - "integrity": "sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==", - "dev": true, - "license": "MIT" - }, - "node_modules/safe-buffer": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", - "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", - "dev": true, - "license": "MIT" - }, - "node_modules/safer-buffer": { - "version": "2.1.2", - "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", - "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", - "dev": true, - "license": "MIT" - }, - "node_modules/secure-compare": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/secure-compare/-/secure-compare-3.0.1.tgz", - "integrity": "sha512-AckIIV90rPDcBcglUwXPF3kg0P0qmPsPXAj6BBEENQE1p5yA1xfmDJzfi1Tappj37Pv2mVbKpL3Z1T+Nn7k1Qw==", - "dev": true, - "license": "MIT" - }, - "node_modules/set-function-length": { - "version": "1.2.2", - "resolved": "https://registry.npmjs.org/set-function-length/-/set-function-length-1.2.2.tgz", - "integrity": "sha512-pgRc4hJ4/sNjWCSS9AmnS40x3bNMDTknHgL5UaMBTMyJnU90EgWh1Rz+MC9eFu4BuN/UwZjKQuY/1v3rM7HMfg==", - "dev": true, - "license": "MIT", - "dependencies": { - "define-data-property": "^1.1.4", - "es-errors": "^1.3.0", - "function-bind": "^1.1.2", - "get-intrinsic": "^1.2.4", - "gopd": "^1.0.1", - "has-property-descriptors": "^1.0.2" - }, - "engines": { - "node": ">= 0.4" - } - }, - "node_modules/side-channel": { - "version": "1.0.6", - "resolved": "https://registry.npmjs.org/side-channel/-/side-channel-1.0.6.tgz", - "integrity": "sha512-fDW/EZ6Q9RiO8eFG8Hj+7u/oW+XrPTIChwCOM2+th2A6OblDtYYIpve9m+KvI9Z4C9qSEXlaGR6bTEYHReuglA==", - "dev": true, - "license": "MIT", - "dependencies": { - "call-bind": "^1.0.7", - "es-errors": "^1.3.0", - "get-intrinsic": "^1.2.4", - "object-inspect": "^1.13.1" - }, - "engines": { - "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" - } - }, - "node_modules/supports-color": { - "version": "7.2.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", - "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", - "dev": true, - "license": "MIT", - "dependencies": { - "has-flag": "^4.0.0" - }, - "engines": { - "node": ">=8" - } - }, - "node_modules/union": { - "version": "0.5.0", - "resolved": "https://registry.npmjs.org/union/-/union-0.5.0.tgz", - "integrity": "sha512-N6uOhuW6zO95P3Mel2I2zMsbsanvvtgn6jVqJv4vbVcz/JN0OkL9suomjQGmWtxJQXOCqUJvquc1sMeNz/IwlA==", - "dev": true, - "dependencies": { - "qs": "^6.4.0" - }, - "engines": { - "node": ">= 0.8.0" - } - }, - "node_modules/url-join": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/url-join/-/url-join-4.0.1.tgz", - "integrity": "sha512-jk1+QP6ZJqyOiuEI9AEWQfju/nB2Pw466kbA0LEZljHwKeMgd9WrAEgEGxjPDD2+TNbbb37rTyhEfrCXfuKXnA==", - "dev": true, - "license": "MIT" - }, - "node_modules/whatwg-encoding": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/whatwg-encoding/-/whatwg-encoding-2.0.0.tgz", - "integrity": "sha512-p41ogyeMUrw3jWclHWTQg1k05DSVXPLcVxRTYsXUk+ZooOCZLcoYgPZ/HL/D/N+uQPOtcp1me1WhBEaX02mhWg==", - "dev": true, - "license": "MIT", - "dependencies": { - "iconv-lite": "0.6.3" - }, - "engines": { - "node": ">=12" - } - } - } -} diff --git a/examples/bare-js/package.json b/examples/bare-js/package.json index 1f00867..3ff4065 100644 --- a/examples/bare-js/package.json +++ b/examples/bare-js/package.json @@ -4,8 +4,8 @@ "type": "module", "scripts": { "build": "node ./bundle.mjs", - "server": "http-server", - "test": "echo \"Error: no test specified\" && exit 1" + "dev": "pnpm run server", + "server": "http-server" }, "keywords": [], "author": "", @@ -14,7 +14,5 @@ "devDependencies": { "http-server": "^14.1.1" }, - "dependencies": { - "@fedimint/core-web": "workspace:*" - } + "packageManager": "pnpm@9.4.0" } diff --git a/examples/bare-js/style.css b/examples/bare-js/style.css new file mode 100644 index 0000000..9059be0 --- /dev/null +++ b/examples/bare-js/style.css @@ -0,0 +1,69 @@ +body { + font-family: Arial, sans-serif; + margin: 0; + padding: 0; + font-size: 16px; + line-height: 1.5; +} + +.container { + max-width: 800px; + margin: 0 auto; + padding: 20px; + box-sizing: border-box; +} + +h2 { + font-size: 28px; + margin-bottom: 20px; +} + +#console { + border: 1px solid #ccc; + padding: 10px; + font-family: monospace; + white-space: pre-wrap; + height: 300px; + overflow-y: auto; + margin-bottom: 20px; + font-size: 18px; +} + +#actions { + display: flex; + flex-direction: column; + gap: 15px; + margin-bottom: 20px; +} + +button { + padding: 15px; + cursor: pointer; + font-size: 18px; + border: none; + border-radius: 5px; +} + +@media (max-width: 600px) { + body { + font-size: 18px; + } + + .container { + padding: 15px; + } + + h2 { + font-size: 32px; + } + + #console { + font-size: 14px; + height: 250px; + } + + button { + font-size: 14px; + padding: 18px; + } +} diff --git a/examples/nextjs/next-env.d.ts b/examples/nextjs/next-env.d.ts deleted file mode 100644 index 40c3d68..0000000 --- a/examples/nextjs/next-env.d.ts +++ /dev/null @@ -1,5 +0,0 @@ -/// -/// - -// NOTE: This file should not be edited -// see https://nextjs.org/docs/app/building-your-application/configuring/typescript for more information. diff --git a/examples/vite-core/README.md b/examples/vite-core/README.md index c79a780..722f7c7 100644 --- a/examples/vite-core/README.md +++ b/examples/vite-core/README.md @@ -2,6 +2,12 @@ This is an example application demonstrating the usage of Fedimint client in a simple web application. [(demo)](https://fedimint.github.io/fedimint-web-sdk/) +## Deploy preview + +You can preview this example live with [StackBlitz](https://stackblitz.com/github/fedimint/fedimint-web-sdk/tree/main/examples/vite-core) + +[![Open in StackBlitz](https://developer.stackblitz.com/img/open_in_stackblitz.svg)](https://stackblitz.com/github/fedimint/fedimint-web-sdk/tree/main/examples/vite-core) + ## Technologies Used - core-web: The Fedimint client library for web applications @@ -17,5 +23,10 @@ This is an example application demonstrating the usage of Fedimint client in a s ```bash # from the root of the repo + +# install dependencies +pnpm i + +# run the dev server pnpm run dev:vite ``` diff --git a/examples/vite-core/package.json b/examples/vite-core/package.json index b931f68..eed9585 100644 --- a/examples/vite-core/package.json +++ b/examples/vite-core/package.json @@ -4,24 +4,24 @@ "type": "module", "scripts": { "dev": "vite", - "build": "tsc && vite build", - "build:pages": "tsc && vite build --base /fedimint-web-sdk/", - "preview": "vite preview --base /fedimint-web-sdk/", - "preview:pages": "vite preview --base /fedimint-web-sdk/", + "build": "vite build", + "preview": "vite preview", "clean": "rm -rf dist tsconfig.tsbuildinfo", "clean:deep": "pnpm run clean && rm -rf node_modules" }, "dependencies": { - "@fedimint/core-web": "workspace:*", + "@fedimint/core-web": "canary", "react": "^18.3.1", - "react-dom": ">=18.3.1" + "react-dom": "^18.3.1" }, "devDependencies": { "@types/react": ">=18.3.1", "@types/react-dom": "^18.3.0", "@vitejs/plugin-react": "^4.3.1", "buffer": "^6.0.3", + "typescript": "^5.2.2", "vite": "^5.3.2", "vite-plugin-wasm": "^3.3.0" - } + }, + "packageManager": "pnpm@9.4.0" } diff --git a/examples/vite-core/src/App.tsx b/examples/vite-core/src/App.tsx index 4ef687e..6e9dd2c 100644 --- a/examples/vite-core/src/App.tsx +++ b/examples/vite-core/src/App.tsx @@ -48,7 +48,28 @@ const App = () => { <>

Fedimint Typescript Library Demo

-

This is a WIP

+ +
+ Steps to get started: +
    +
  1. Join a Federation (persists across sessions)
  2. +
  3. Generate an Invoice
  4. +
  5. + Pay the Invoice using the{' '} + + mutinynet faucet + +
  6. +
  7. + Investigate the Browser Tools +
      +
    • Browser Console for logs
    • +
    • Network Tab (websocket) for guardian requests
    • +
    • Application Tab for state
    • +
    +
  8. +
+
@@ -270,6 +291,12 @@ const GenerateLightningInvoice = () => { {generating ? 'Generating...' : 'Generate Invoice'} +
+ mutinynet faucet:{' '} + + https://faucet.mutinynet.com/ + +
{invoice && (
Generated Invoice: diff --git a/examples/vite-core/src/index.css b/examples/vite-core/src/index.css index bc3c1e9..dac231d 100644 --- a/examples/vite-core/src/index.css +++ b/examples/vite-core/src/index.css @@ -37,6 +37,12 @@ header { text-align: center; } +.steps { + text-align: left; + display: inline-block; + font-size: 1.2rem; +} + main { display: flex; flex-direction: column; diff --git a/package.json b/package.json index b1ccb20..804ccff 100644 --- a/package.json +++ b/package.json @@ -3,11 +3,10 @@ "type": "module", "scripts": { "build": "pnpm run --r --filter \"./packages/**\" build", - "build:pages": "pnpm --filter vite-core build:pages", "clean": "pnpm run --r --parallel clean && rm -rf packages/**/*.json.tmp", "clean:deep": "rm -rf node_modules && pnpm run --r --parallel clean:deep", "deps": "pnpx taze -r", - "dev": "pnpm dev:vite", + "dev": "pnpm build && pnpm dev:vite", "dev:vite": "pnpm --filter vite-core dev", "dev:bare": "pnpm run --filter bare-js server", "docs:dev": "pnpm run --filter docs docs:dev", @@ -21,7 +20,7 @@ "prepare": "pnpm simple-git-hooks", "preview": "pnpm --filter vite-core preview", "release": "pnpm run build && pnpm changeset publish", - "reset": "pnpm clean && pnpm build && pnpm build:pages && pnpm preview", + "reset": "pnpm clean && pnpm build && pnpm preview", "changeset": "changeset", "version": "changeset version", "typecheck": "pnpm run --r --parallel typecheck", diff --git a/packages/core-web/README.md b/packages/core-web/README.md index 7e401cd..46fff7a 100644 --- a/packages/core-web/README.md +++ b/packages/core-web/README.md @@ -69,7 +69,7 @@ const unsubscribe = wallet.balance.subscribeBalance((balance: number) => { await wallet.mint.reissueNotes('A11qgqpw9thwvaz7t...') // Pay Lightning Invoice -await wallet.lightning.payBolt11Invoice('lnbc...') +await wallet.lightning.payInvoice('lnbc...') ``` ### Check out the example diff --git a/packages/core-web/src/FedimintWallet.test.ts b/packages/core-web/src/FedimintWallet.test.ts index e3d579c..f0bede3 100644 --- a/packages/core-web/src/FedimintWallet.test.ts +++ b/packages/core-web/src/FedimintWallet.test.ts @@ -1,18 +1,15 @@ -import { test, expect, vi } from 'vitest' -import { FedimintWallet } from './FedimintWallet' +import { test, expect } from 'vitest' +import { TestFedimintWallet } from './test/TestFedimintWallet' import { beforeAll } from 'vitest' let randomTestingId: string -let wallet: FedimintWallet -// Testnet -const TESTING_FEDERATION = - 'fed11qgqrgvnhwden5te0v9k8q6rp9ekh2arfdeukuet595cr2ttpd3jhq6rzve6zuer9wchxvetyd938gcewvdhk6tcqqysptkuvknc7erjgf4em3zfh90kffqf9srujn6q53d6r056e4apze5cw27h75' +let wallet: TestFedimintWallet beforeAll(() => { randomTestingId = Math.random().toString(36).substring(2, 15) - wallet = new FedimintWallet() - expect(wallet._testing).toBeDefined() - expect(wallet._testing!.getRequestCounter()).toBe(1) + wallet = new TestFedimintWallet() + expect(wallet.testing).toBeDefined() + expect(wallet.testing.getRequestCounter()).toBe(1) expect(wallet).toBeDefined() // Cleanup after all tests @@ -32,11 +29,11 @@ test('initial open & join', async () => { // On initial open, it should return false // because no federations have been joined await expect(wallet.open(randomTestingId)).resolves.toBe(false) - const beforeJoin = wallet._testing!.getRequestCounter() + const beforeJoin = wallet.testing.getRequestCounter() await expect( - wallet.joinFederation(TESTING_FEDERATION, randomTestingId), + wallet.joinFederation(wallet.testing.TESTING_INVITE, randomTestingId), ).resolves.toBeUndefined() - expect(wallet._testing!.getRequestCounter()).toBe(beforeJoin + 1) + expect(wallet.testing.getRequestCounter()).toBe(beforeJoin + 1) expect(wallet.isOpen()).toBe(true) await expect(wallet.waitForOpen()).resolves.toBeUndefined() }) @@ -56,7 +53,7 @@ test('Error on open & join if wallet is already open', async () => { // Test joining federation on an already open wallet try { - await wallet.joinFederation(TESTING_FEDERATION, randomTestingId) + await wallet.joinFederation(wallet.testing.TESTING_INVITE, randomTestingId) expect.unreachable('Joining a federation should fail on an open wallet') } catch (error) { expect(error).toBeInstanceOf(Error) diff --git a/packages/core-web/src/FedimintWallet.ts b/packages/core-web/src/FedimintWallet.ts index bd81da4..ab2de2a 100644 --- a/packages/core-web/src/FedimintWallet.ts +++ b/packages/core-web/src/FedimintWallet.ts @@ -7,7 +7,6 @@ import { RecoveryService, } from './services' import { logger, type LogLevel } from './utils/logger' -import { TestingService } from './services/TestingService' const DEFAULT_CLIENT_NAME = 'fm-default' as const @@ -20,8 +19,6 @@ export class FedimintWallet { public federation: FederationService public recovery: RecoveryService - public _testing?: TestingService - private _openPromise: Promise | null = null private _resolveOpen: () => void = () => {} private _isOpen: boolean = false @@ -65,9 +62,6 @@ export class FedimintWallet { this.balance = new BalanceService(this._client) this.federation = new FederationService(this._client) this.recovery = new RecoveryService(this._client) - if (process.env.NODE_ENV === 'test') { - this._testing = new TestingService(this._client) - } logger.info('FedimintWallet instantiated') diff --git a/packages/core-web/src/services/BalanceService.test.ts b/packages/core-web/src/services/BalanceService.test.ts index 1612586..8f01186 100644 --- a/packages/core-web/src/services/BalanceService.test.ts +++ b/packages/core-web/src/services/BalanceService.test.ts @@ -1,19 +1,16 @@ import { test, expect } from 'vitest' -import { FedimintWallet } from '../FedimintWallet' +import { TestFedimintWallet } from '../test/TestFedimintWallet' import { beforeAll } from 'vitest' let randomTestingId: string -let wallet: FedimintWallet -// Testnet -const TESTING_FEDERATION = - 'fed11qgqrgvnhwden5te0v9k8q6rp9ekh2arfdeukuet595cr2ttpd3jhq6rzve6zuer9wchxvetyd938gcewvdhk6tcqqysptkuvknc7erjgf4em3zfh90kffqf9srujn6q53d6r056e4apze5cw27h75' +let wallet: TestFedimintWallet beforeAll(async () => { randomTestingId = Math.random().toString(36).substring(2, 15) - wallet = new FedimintWallet() + wallet = new TestFedimintWallet() expect(wallet).toBeDefined() await expect( - wallet.joinFederation(TESTING_FEDERATION, randomTestingId), + wallet.joinFederation(wallet.testing.TESTING_INVITE, randomTestingId), ).resolves.toBeUndefined() expect(wallet.isOpen()).toBe(true) @@ -31,24 +28,22 @@ beforeAll(async () => { test('getBalance should be initially zero', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const beforeGetBalance = wallet._testing!.getRequestCounter() + const beforeGetBalance = wallet.testing.getRequestCounter() await expect(wallet.balance.getBalance()).resolves.toEqual(0) - expect(wallet._testing!.getRequestCounter()).toBe(beforeGetBalance + 1) + expect(wallet.testing.getRequestCounter()).toBe(beforeGetBalance + 1) }) test('subscribe balance', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() - const callbacksBefore = wallet._testing!.getRequestCallbackMap().size + const counterBefore = wallet.testing.getRequestCounter() + const callbacksBefore = wallet.testing.getRequestCallbackMap().size const unsubscribe = await wallet.balance.subscribeBalance((balance) => { expect(balance).toEqual(0) }) - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) - expect(wallet._testing!.getRequestCallbackMap().size).toBe( - callbacksBefore + 1, - ) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCallbackMap().size).toBe(callbacksBefore + 1) await expect(wallet.balance.getBalance()).resolves.toEqual(0) expect(unsubscribe()).toBeUndefined() diff --git a/packages/core-web/src/services/FederationService.test.ts b/packages/core-web/src/services/FederationService.test.ts index 5807324..33986be 100644 --- a/packages/core-web/src/services/FederationService.test.ts +++ b/packages/core-web/src/services/FederationService.test.ts @@ -1,19 +1,16 @@ import { test, expect } from 'vitest' -import { FedimintWallet } from '../FedimintWallet' +import { TestFedimintWallet } from '../test/TestFedimintWallet' import { beforeAll } from 'vitest' let randomTestingId: string -let wallet: FedimintWallet -// Testnet -const TESTING_FEDERATION = - 'fed11qgqrgvnhwden5te0v9k8q6rp9ekh2arfdeukuet595cr2ttpd3jhq6rzve6zuer9wchxvetyd938gcewvdhk6tcqqysptkuvknc7erjgf4em3zfh90kffqf9srujn6q53d6r056e4apze5cw27h75' +let wallet: TestFedimintWallet beforeAll(async () => { randomTestingId = Math.random().toString(36).substring(2, 15) - wallet = new FedimintWallet() + wallet = new TestFedimintWallet() expect(wallet).toBeDefined() await expect( - wallet.joinFederation(TESTING_FEDERATION, randomTestingId), + wallet.joinFederation(wallet.testing.TESTING_INVITE, randomTestingId), ).resolves.toBeUndefined() expect(wallet.isOpen()).toBe(true) @@ -31,7 +28,7 @@ beforeAll(async () => { test('getConfig should return the federation config', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() await expect(wallet.federation.getConfig()).resolves.toMatchObject({ api_endpoints: expect.any(Object), broadcast_public_keys: expect.any(Object), @@ -39,36 +36,35 @@ test('getConfig should return the federation config', async () => { meta: expect.any(Object), modules: expect.any(Object), }) - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) }) test('getFederationId should return the federation id', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() const federationId = await wallet.federation.getFederationId() expect(federationId).toBeTypeOf('string') expect(federationId).toHaveLength(64) - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) }) test('getInviteCode should return the invite code', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() const inviteCode = await wallet.federation.getInviteCode(0) expect(inviteCode).toBeTypeOf('string') - expect(inviteCode).toHaveLength(154) - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) }) test('listOperations should return the list of operations', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() await expect(wallet.federation.listOperations()).resolves.toMatchObject([]) - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) }) diff --git a/packages/core-web/src/services/LightningService.test.ts b/packages/core-web/src/services/LightningService.test.ts index 8d91390..3e9b7aa 100644 --- a/packages/core-web/src/services/LightningService.test.ts +++ b/packages/core-web/src/services/LightningService.test.ts @@ -1,19 +1,16 @@ import { test, expect } from 'vitest' -import { FedimintWallet } from '../FedimintWallet' +import { TestFedimintWallet } from '../test/TestFedimintWallet' import { beforeAll } from 'vitest' let randomTestingId: string -let wallet: FedimintWallet -// Testnet -const TESTING_FEDERATION = - 'fed11qgqrgvnhwden5te0v9k8q6rp9ekh2arfdeukuet595cr2ttpd3jhq6rzve6zuer9wchxvetyd938gcewvdhk6tcqqysptkuvknc7erjgf4em3zfh90kffqf9srujn6q53d6r056e4apze5cw27h75' +let wallet: TestFedimintWallet beforeAll(async () => { randomTestingId = Math.random().toString(36).substring(2, 15) - wallet = new FedimintWallet() + wallet = new TestFedimintWallet() expect(wallet).toBeDefined() await expect( - wallet.joinFederation(TESTING_FEDERATION, randomTestingId), + wallet.joinFederation(wallet.testing.TESTING_INVITE, randomTestingId), ).resolves.toBeUndefined() expect(wallet.isOpen()).toBe(true) @@ -32,7 +29,7 @@ test('createInvoice should create a bolt11 invoice', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() const invoice = await wallet.lightning.createInvoice(100, 'test') expect(invoice).toBeDefined() expect(invoice).toMatchObject({ @@ -41,7 +38,7 @@ test('createInvoice should create a bolt11 invoice', async () => { }) // 3 requests were made, one for the invoice, one for refreshing the // gateway cache, one for getting the gateway info - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 3) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 3) // Test with expiry time await expect( @@ -53,9 +50,9 @@ test('listGateways should return a list of gateways', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() const gateways = await wallet.lightning.listGateways() - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) expect(gateways).toBeDefined() expect(gateways).toMatchObject([ { @@ -68,18 +65,18 @@ test('updateGatewayCache should update the gateway cache', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() await expect(wallet.lightning.updateGatewayCache()).resolves.toBeDefined() - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) }) test('getGateway should return a gateway', async () => { expect(wallet).toBeDefined() expect(wallet.isOpen()).toBe(true) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() const gateway = await wallet.lightning.getGateway() - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) expect(gateway).toMatchObject({ api: expect.any(String), fees: expect.any(Object), @@ -100,7 +97,7 @@ test('createInvoiceWithGateway should create a bolt11 invoice with a gateway', a const gateway = gateways[0] expect(gateway).toBeDefined() - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() const invoice = await wallet.lightning.createInvoiceWithGateway( 100, 'test', @@ -113,7 +110,7 @@ test('createInvoiceWithGateway should create a bolt11 invoice with a gateway', a invoice: expect.any(String), operation_id: expect.any(String), }) - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 1) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 1) await expect( wallet.lightning.createInvoiceWithGateway( 100, @@ -136,7 +133,7 @@ test('payInvoice should pay a bolt11 invoice', async () => { operation_id: expect.any(String), }) - const counterBefore = wallet._testing!.getRequestCounter() + const counterBefore = wallet.testing.getRequestCounter() // Insufficient funds try { await wallet.lightning.payInvoice(invoice.invoice, {}) @@ -146,5 +143,5 @@ test('payInvoice should pay a bolt11 invoice', async () => { } // 3 requests were made, one for paying the invoice, one for refreshing the // gateway cache, one for getting the gateway info - expect(wallet._testing!.getRequestCounter()).toBe(counterBefore + 3) + expect(wallet.testing.getRequestCounter()).toBe(counterBefore + 3) }) diff --git a/packages/core-web/src/test/TestFedimintWallet.ts b/packages/core-web/src/test/TestFedimintWallet.ts new file mode 100644 index 0000000..38458fc --- /dev/null +++ b/packages/core-web/src/test/TestFedimintWallet.ts @@ -0,0 +1,17 @@ +import { FedimintWallet } from '../FedimintWallet' +import { WorkerClient } from '../worker/WorkerClient' +import { TestingService } from './TestingService' + +export class TestFedimintWallet extends FedimintWallet { + public testing: TestingService + + constructor() { + super() + this.testing = new TestingService(this.getWorkerClient()) + } + + // Method to expose the WorkerClient + getWorkerClient(): WorkerClient { + return this['_client'] + } +} diff --git a/packages/core-web/src/services/TestingService.ts b/packages/core-web/src/test/TestingService.ts similarity index 54% rename from packages/core-web/src/services/TestingService.ts rename to packages/core-web/src/test/TestingService.ts index 3ef5fbc..42932d4 100644 --- a/packages/core-web/src/services/TestingService.ts +++ b/packages/core-web/src/test/TestingService.ts @@ -3,7 +3,12 @@ import { WorkerClient } from '../worker' // This is a testing service that allows for inspecting the internals // of the WorkerClient. It is not intended for use in production. export class TestingService { - constructor(private client: WorkerClient) {} + public TESTING_INVITE: string + constructor(private client: WorkerClient) { + // Solo Mint on mutinynet + this.TESTING_INVITE = + 'fed11qgqrsdnhwden5te0v9cxjtt4dekxzamxw4kz6mmjvvkhydted9ukg6r9xfsnx7th0fhn26tf093juamwv4u8gtnpwpcz7qqpyz0e327ua8geceutfrcaezwt22mk6s2rdy09kg72jrcmncng2gn0kp2m5sk' + } getRequestCounter() { return this.client._getRequestCounter() diff --git a/packages/core-web/tsconfig.json b/packages/core-web/tsconfig.json index b4c474d..da5a3d7 100644 --- a/packages/core-web/tsconfig.json +++ b/packages/core-web/tsconfig.json @@ -10,5 +10,5 @@ "types": ["node"] }, "include": ["src/**/*.ts"], - "exclude": ["node_modules", "src/**/*.test.ts"] + "exclude": ["node_modules", "src/**/*.test.ts", "src/test"] } diff --git a/packages/react/package.json b/packages/react/package.json index da33d1e..7700924 100644 --- a/packages/react/package.json +++ b/packages/react/package.json @@ -8,7 +8,7 @@ "lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0", "preview": "vite preview" }, - "dependencies": { + "peerDependencies": { "react": "^18.3.1", "react-dom": ">=18.3.1" }, diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 13fc15f..909ff1a 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -61,16 +61,12 @@ importers: version: 11.2.1 vitepress: specifier: ^1.3.4 - version: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.4)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4) + version: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.10)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4) vitepress-plugin-mermaid: specifier: ^2.0.17 - version: 2.0.17(mermaid@11.2.1)(vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.4)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4)) + version: 2.0.17(mermaid@11.2.1)(vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.10)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4)) examples/bare-js: - dependencies: - '@fedimint/core-web': - specifier: workspace:* - version: link:../../packages/core-web devDependencies: http-server: specifier: ^14.1.1 @@ -79,33 +75,36 @@ importers: examples/vite-core: dependencies: '@fedimint/core-web': - specifier: workspace:* - version: link:../../packages/core-web + specifier: canary + version: 0.0.0-canary-20240927003217 react: specifier: ^18.3.1 version: 18.3.1 react-dom: - specifier: '>=18.3.1' + specifier: ^18.3.1 version: 18.3.1(react@18.3.1) devDependencies: '@types/react': specifier: '>=18.3.1' - version: 18.3.4 + version: 18.3.10 '@types/react-dom': specifier: ^18.3.0 version: 18.3.0 '@vitejs/plugin-react': specifier: ^4.3.1 - version: 4.3.1(vite@5.4.2(@types/node@22.5.5)(terser@5.32.0)) + version: 4.3.1(vite@5.4.8(@types/node@22.5.5)(terser@5.32.0)) buffer: specifier: ^6.0.3 version: 6.0.3 + typescript: + specifier: ^5.2.2 + version: 5.5.2 vite: specifier: ^5.3.2 - version: 5.4.2(@types/node@22.5.5)(terser@5.32.0) + version: 5.4.8(@types/node@22.5.5)(terser@5.32.0) vite-plugin-wasm: specifier: ^3.3.0 - version: 3.3.0(vite@5.4.2(@types/node@22.5.5)(terser@5.32.0)) + version: 3.3.0(vite@5.4.8(@types/node@22.5.5)(terser@5.32.0)) packages/core-web: dependencies: @@ -614,6 +613,12 @@ packages: resolution: {integrity: sha512-Ys+3g2TaW7gADOJzPt83SJtCDhMjndcDMFVQ/Tj9iA1BfJzFKD9mAUXT3OenpuPHbI6P/myECxRJrofUsDx/5g==} engines: {node: ^12.22.0 || ^14.17.0 || >=16.0.0} + '@fedimint/core-web@0.0.0-canary-20240927003217': + resolution: {integrity: sha512-fuFuCktNP7HYSLDL5DYNkgbHsRseRXN026+wXPS6K9qr7m+HebPGRSIzMSm7ieg5mdg6c34z4BMDa/4Y1kAr9w==} + + '@fedimint/fedimint-client-wasm-bundler@0.0.0-canary-20240927003217': + resolution: {integrity: sha512-dwFVFBSrDqGzhRuXKDxTuYFFRJ5zIh3zpLz7185+nb3m8jxktQFGrf8LRTjZHv9BajmI6AtpAbI6QUuQfURduA==} + '@humanwhocodes/config-array@0.11.14': resolution: {integrity: sha512-3T8LkOmg45BV5FICb15QQMsyUSWrQ8AygVfC7ZG32zOalnqrilm018ZVCw0eapXux8FtA33q8PSRSstjee3jSg==} engines: {node: '>=10.10.0'} @@ -929,6 +934,9 @@ packages: '@types/react-dom@18.3.0': resolution: {integrity: sha512-EhwApuTmMBmXuFOikhQLIBUn6uFg81SwLMOAUgodJF14SOBOCMdU04gDoYi0WOJJHD144TL32z4yDqCW3dnkQg==} + '@types/react@18.3.10': + resolution: {integrity: sha512-02sAAlBnP39JgXwkAq3PeU9DVaaGpZyF3MGcC0MKgQVkZor5IiiDAipVaxQHtDJAmO4GIy/rVBy/LzVj76Cyqg==} + '@types/react@18.3.4': resolution: {integrity: sha512-J7W30FTdfCxDDjmfRM+/JqLHBIyl7xUIp9kwK637FGmY7+mkSFSe6L4jpZzhj5QMfLssSDP4/i75AKkrdC7/Jw==} @@ -2995,6 +3003,37 @@ packages: terser: optional: true + vite@5.4.8: + resolution: {integrity: sha512-FqrItQ4DT1NC4zCUqMB4c4AZORMKIa0m8/URVCZ77OZ/QSNeJ54bU1vrFADbDsuwfIPcgknRkmqakQcgnL4GiQ==} + engines: {node: ^18.0.0 || >=20.0.0} + hasBin: true + peerDependencies: + '@types/node': ^18.0.0 || >=20.0.0 + less: '*' + lightningcss: ^1.21.0 + sass: '*' + sass-embedded: '*' + stylus: '*' + sugarss: '*' + terser: ^5.4.0 + peerDependenciesMeta: + '@types/node': + optional: true + less: + optional: true + lightningcss: + optional: true + sass: + optional: true + sass-embedded: + optional: true + stylus: + optional: true + sugarss: + optional: true + terser: + optional: true + vitepress-plugin-mermaid@2.0.17: resolution: {integrity: sha512-IUzYpwf61GC6k0XzfmAmNrLvMi9TRrVRMsUyCA8KNXhg/mQ1VqWnO0/tBVPiX5UoKF1mDUwqn5QV4qAJl6JnUg==} peerDependencies: @@ -3608,9 +3647,9 @@ snapshots: '@docsearch/css@3.6.1': {} - '@docsearch/js@3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)': + '@docsearch/js@3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)': dependencies: - '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2) + '@docsearch/react': 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2) preact: 10.24.1 transitivePeerDependencies: - '@algolia/client-search' @@ -3619,14 +3658,14 @@ snapshots: - react-dom - search-insights - '@docsearch/react@3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)': + '@docsearch/react@3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)': dependencies: '@algolia/autocomplete-core': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0)(search-insights@2.17.2) '@algolia/autocomplete-preset-algolia': 1.9.3(@algolia/client-search@4.24.0)(algoliasearch@4.24.0) '@docsearch/css': 3.6.1 algoliasearch: 4.24.0 optionalDependencies: - '@types/react': 18.3.4 + '@types/react': 18.3.10 react: 18.3.1 react-dom: 18.3.1(react@18.3.1) search-insights: 2.17.2 @@ -3725,6 +3764,12 @@ snapshots: '@eslint/js@8.57.0': {} + '@fedimint/core-web@0.0.0-canary-20240927003217': + dependencies: + '@fedimint/fedimint-client-wasm-bundler': 0.0.0-canary-20240927003217 + + '@fedimint/fedimint-client-wasm-bundler@0.0.0-canary-20240927003217': {} + '@humanwhocodes/config-array@0.11.14': dependencies: '@humanwhocodes/object-schema': 2.0.3 @@ -4074,7 +4119,12 @@ snapshots: '@types/react-dom@18.3.0': dependencies: - '@types/react': 18.3.4 + '@types/react': 18.3.10 + + '@types/react@18.3.10': + dependencies: + '@types/prop-types': 15.7.12 + csstype: 3.1.3 '@types/react@18.3.4': dependencies: @@ -4191,6 +4241,17 @@ snapshots: transitivePeerDependencies: - supports-color + '@vitejs/plugin-react@4.3.1(vite@5.4.8(@types/node@22.5.5)(terser@5.32.0))': + dependencies: + '@babel/core': 7.25.2 + '@babel/plugin-transform-react-jsx-self': 7.24.7(@babel/core@7.25.2) + '@babel/plugin-transform-react-jsx-source': 7.24.7(@babel/core@7.25.2) + '@types/babel__core': 7.20.5 + react-refresh: 0.14.2 + vite: 5.4.8(@types/node@22.5.5)(terser@5.32.0) + transitivePeerDependencies: + - supports-color + '@vitejs/plugin-vue@5.1.4(vite@5.4.2(@types/node@22.5.5)(terser@5.32.0))(vue@3.5.8(typescript@5.5.4))': dependencies: vite: 5.4.2(@types/node@22.5.5)(terser@5.32.0) @@ -6205,7 +6266,7 @@ snapshots: cac: 6.7.14 debug: 4.3.6 pathe: 1.1.2 - vite: 5.4.2(@types/node@20.16.1)(terser@5.32.0) + vite: 5.4.8(@types/node@20.16.1)(terser@5.32.0) transitivePeerDependencies: - '@types/node' - less @@ -6221,9 +6282,9 @@ snapshots: dependencies: vite: 5.4.2(@types/node@20.16.1)(terser@5.32.0) - vite-plugin-wasm@3.3.0(vite@5.4.2(@types/node@22.5.5)(terser@5.32.0)): + vite-plugin-wasm@3.3.0(vite@5.4.8(@types/node@22.5.5)(terser@5.32.0)): dependencies: - vite: 5.4.2(@types/node@22.5.5)(terser@5.32.0) + vite: 5.4.8(@types/node@22.5.5)(terser@5.32.0) vite@5.4.2(@types/node@20.16.1)(terser@5.32.0): dependencies: @@ -6245,17 +6306,37 @@ snapshots: fsevents: 2.3.3 terser: 5.32.0 - vitepress-plugin-mermaid@2.0.17(mermaid@11.2.1)(vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.4)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4)): + vite@5.4.8(@types/node@20.16.1)(terser@5.32.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.47 + rollup: 4.21.2 + optionalDependencies: + '@types/node': 20.16.1 + fsevents: 2.3.3 + terser: 5.32.0 + + vite@5.4.8(@types/node@22.5.5)(terser@5.32.0): + dependencies: + esbuild: 0.21.5 + postcss: 8.4.47 + rollup: 4.21.2 + optionalDependencies: + '@types/node': 22.5.5 + fsevents: 2.3.3 + terser: 5.32.0 + + vitepress-plugin-mermaid@2.0.17(mermaid@11.2.1)(vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.10)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4)): dependencies: mermaid: 11.2.1 - vitepress: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.4)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4) + vitepress: 1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.10)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4) optionalDependencies: '@mermaid-js/mermaid-mindmap': 9.3.0 - vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.4)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4): + vitepress@1.3.4(@algolia/client-search@4.24.0)(@types/node@22.5.5)(@types/react@18.3.10)(postcss@8.4.47)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2)(terser@5.32.0)(typescript@5.5.4): dependencies: '@docsearch/css': 3.6.1 - '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.4)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2) + '@docsearch/js': 3.6.1(@algolia/client-search@4.24.0)(@types/react@18.3.10)(react-dom@18.3.1(react@18.3.1))(react@18.3.1)(search-insights@2.17.2) '@shikijs/core': 1.18.0 '@shikijs/transformers': 1.18.0 '@types/markdown-it': 14.1.2