@nevermined-io/ui-widgets 1.2.1 → 1.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.d.ts CHANGED
@@ -9,6 +9,6 @@ export { WidgetApiError, WidgetInitError, WidgetSessionExpiredError } from './ut
9
9
  export type { WidgetConfig, WidgetSession, WidgetAccount, Environment, EmbedError, WidgetSuccessHandle, WidgetSuccessEvent, } from './types.js';
10
10
  export type { IframeOptions } from './iframe-manager.js';
11
11
  export type { CheckoutOptions, CheckoutResult } from './widgets/checkout.js';
12
- export type { CardAction, CreateDelegationOptions, CreateDelegationResult, EnrollCardOptions, EnrollCardProvider, EnrollCardResult, ListCardsOptions, } from './widgets/delegations.js';
12
+ export type { CardAction, CreateDelegationOptions, CreateDelegationResult, EnrollCardOptions, EnrollCardProvider, EnrollCardResult, ListCardsOptions, SetupCardOptions, SetupCardResult, WidgetIframeCss, } from './widgets/delegations.js';
13
13
  export type { WidgetMessage, ParseResult } from './messages.js';
14
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,YAAY,GACb,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAC9F,YAAY,EACV,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC5E,YAAY,EACV,UAAU,EACV,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,GACjB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAA;AAC3D,OAAO,EAAE,cAAc,EAAE,MAAM,cAAc,CAAA;AAC7C,OAAO,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AACtD,OAAO,EAAE,iBAAiB,EAAE,MAAM,0BAA0B,CAAA;AAC5D,OAAO,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAA;AACtD,OAAO,EACL,iBAAiB,EACjB,sBAAsB,EACtB,aAAa,EACb,YAAY,GACb,MAAM,eAAe,CAAA;AACtB,OAAO,EAAE,cAAc,EAAE,eAAe,EAAE,yBAAyB,EAAE,MAAM,mBAAmB,CAAA;AAC9F,YAAY,EACV,YAAY,EACZ,aAAa,EACb,aAAa,EACb,WAAW,EACX,UAAU,EACV,mBAAmB,EACnB,kBAAkB,GACnB,MAAM,YAAY,CAAA;AACnB,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAA;AACxD,YAAY,EAAE,eAAe,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAA;AAC5E,YAAY,EACV,UAAU,EACV,uBAAuB,EACvB,sBAAsB,EACtB,iBAAiB,EACjB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,EACf,eAAe,GAChB,MAAM,0BAA0B,CAAA;AACjC,YAAY,EAAE,aAAa,EAAE,WAAW,EAAE,MAAM,eAAe,CAAA"}
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.NeverminedWidgets={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=[`local`,`sandbox`,`live`,`staging_sandbox`,`staging_live`],n={local:`http://localhost:3001`,sandbox:`https://api.sandbox.nevermined.app`,live:`https://api.live.nevermined.app`,staging_sandbox:`https://api.sandbox.nevermined.dev`,staging_live:`https://api.live.nevermined.dev`},r={local:`http://localhost:4250`,sandbox:`https://embed.nevermined.app`,live:`https://embed.nevermined.app`,staging_sandbox:`https://embed.nevermined.dev`,staging_live:`https://embed.nevermined.dev`};function i(e){return n[e]}function a(e){return r[e]}var o={local:`sandbox`,sandbox:`sandbox`,live:`live`,staging_sandbox:`sandbox`,staging_live:`live`};function s(e){return o[e]}var c={MISSING_SESSION:{numericCode:`WDG.0001`,message:`session is required — pass the WidgetSession returned by createWidgetSession on the backend`},INVALID_ENVIRONMENT:{numericCode:`WDG.0002`,message:`environment must be one of: sandbox, live, staging_sandbox, staging_live, local`},INVALID_SESSION:{numericCode:`WDG.0003`,message:`session is missing required fields`},SESSION_EXPIRED:{numericCode:`WDG.0006`,message:`Widget session has expired`}},l=class extends Error{code;constructor(e,t,n){super(t??c[e].message,{cause:n}),this.code=e,this.name=`WidgetInitError`}},u=class extends Error{code=`SESSION_EXPIRED`;constructor(){super(c.SESSION_EXPIRED.message),this.name=`WidgetSessionExpiredError`}},d=class extends Error{status;apiCode;constructor(e,t,n){super(e),this.status=t,this.apiCode=n,this.name=`WidgetApiError`}},f=.8,p=class{session;expiresMs;timer=null;constructor(e){this.session=e,this.expiresMs=new Date(e.expiresAt).getTime(),Number.isNaN(this.expiresMs)&&console.warn(`[SessionManager] malformed expiresAt, session will be treated as expired:`,e.expiresAt)}isValid(){return!Number.isNaN(this.expiresMs)&&this.expiresMs>Date.now()}getToken(){return this.session.sessionToken}getSession(){return this.session}startAutoRefresh(e,t){if(this.stopAutoRefresh(),!this.isValid()){t();return}let n=Math.max(0,Math.floor((this.expiresMs-Date.now())*f));this.timer=setTimeout(()=>{this.timer=null,e().then(n=>{if(this.session=n,this.expiresMs=new Date(n.expiresAt).getTime(),!this.isValid()){t();return}this.startAutoRefresh(e,t)},e=>{console.error(`[SessionManager] session refresh failed:`,e),t()})},n)}stopAutoRefresh(){this.timer!==null&&(clearTimeout(this.timer),this.timer=null)}},m=class{listeners=new Map;on(e,t){let n=this.listeners.get(e)??new Set;return n.add(t),this.listeners.set(e,n),this}off(e,t){let n=this.listeners.get(e);return n?(n.delete(t),n.size===0&&this.listeners.delete(e),this):this}once(e,t){let n=r=>{this.off(e,n),t(r)};return this.on(e,n)}removeAllListeners(e){return e===void 0?this.listeners.clear():this.listeners.delete(e),this}emit(e,t){let n=this.listeners.get(e);n&&[...n].forEach(e=>{try{e(t)}catch(e){console.error(`[TypedEventEmitter] Handler threw:`,e)}})}},h=function(e){return e.INIT=`nvm:init`,e.CLOSE=`nvm:close`,e.BOOTED=`nvm:booted`,e.READY=`nvm:ready`,e.RESIZE=`nvm:resize`,e.SUCCESS=`nvm:success`,e.ERROR=`nvm:error`,e.CARD_ACTION=`nvm:card-action`,e}({}),g=`1`,_=`1`;function v(e){return typeof e==`string`&&Object.values(h).includes(e)}function y(e,t){return{type:e,version:_,payload:t}}function b(e){if(typeof e!=`object`||!e)return{ok:!1,reason:`not an object`};let t=e;return v(t.type)?t.version===_?{ok:!0,message:{type:t.type,version:t.version,payload:t.payload}}:{ok:!1,reason:`version mismatch: received "${t.version}", expected "${_}"`}:{ok:!1,reason:typeof t.type==`string`&&t.type.startsWith(`nvm:`)?`unknown nvm: type "${t.type}"`:`missing or unknown type`}}function x(e,t,n){return Math.max(t,Math.min(n,Math.round(e)))}var S=class{expectedOrigin;iframe=null;messageHandlers=new Set;protocolErrorHandlers=new Set;messageListener=null;destroyed=!1;constructor(e){if(this.expectedOrigin=e,e===`*`)throw Error(`[IframeManager] Wildcard origin "*" is not allowed — pass an explicit origin`)}create(e,t){this.iframe?.remove();let n=document.createElement(`iframe`);if(n.src=e,n.style.display=`block`,n.setAttribute(`allow`,`payment *`),n.setAttribute(`sandbox`,`allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation`),!t?.container)n.style.width=`100%`,n.style.height=`100%`,n.style.border=`none`,n.style.position=`fixed`,n.style.top=`0`,n.style.left=`0`,n.style.right=`0`,n.style.bottom=`0`,n.style.zIndex=`9999`;else{let e=x(t.width??480,440,720),r=x(t.height??720,640,960);n.style.width=`${e}px`,n.style.height=`${r}px`,n.style.border=`1px solid #e5e7eb`,n.style.borderRadius=`8px`,n.style.boxSizing=`border-box`}return t?.style&&Object.assign(n.style,t.style),(t?.container??document.body).appendChild(n),this.iframe=n,n}destroy(){this.destroyed=!0,this.messageListener&&=(window.removeEventListener(`message`,this.messageListener),null),this.messageHandlers.clear(),this.protocolErrorHandlers.clear(),this.iframe?.remove(),this.iframe=null}postMessage(e){this.destroyed||this.iframe?.contentWindow?.postMessage(e,this.expectedOrigin)}onMessage(e){return this.destroyed?()=>void 0:(this.messageHandlers.add(e),this.ensureListener(),()=>this.messageHandlers.delete(e))}onProtocolError(e){return this.destroyed?()=>void 0:(this.protocolErrorHandlers.add(e),this.ensureListener(),()=>this.protocolErrorHandlers.delete(e))}ensureListener(){this.messageListener||(this.messageListener=e=>{if(e.origin!==this.expectedOrigin)return;let t=b(e.data);if(!t.ok){console.warn(`[IframeManager] Discarding message from ${this.expectedOrigin}: ${t.reason}`),this.protocolErrorHandlers.forEach(e=>{try{e(t.reason)}catch(e){console.error(`[IframeManager] Protocol error handler threw:`,e)}});return}this.messageHandlers.forEach(e=>{try{e(t.message)}catch(e){console.error(`[IframeManager] Message handler threw:`,e)}})},window.addEventListener(`message`,this.messageListener))}},C={code:`UNKNOWN`,message:`Unknown widget error`},w=class{session;embedBase;embedNetwork;manager=null;destroyed=!1;constructor(e,t,n){this.session=e,this.embedBase=t,this.embedNetwork=n}start(e){if(this.destroyed)throw Error(`[CheckoutWidget] cannot start: instance has been destroyed`);if(!e.did||typeof e.did!=`string`)throw Error(`[CheckoutWidget] did is required`);let t=new URL(`/checkout/${encodeURIComponent(e.did)}`,this.embedBase);e.planId&&t.searchParams.set(`planId`,e.planId),this.mount(t,e,t=>({did:t.did??e.did,planId:t.planId??e.planId,txHash:t.txHash}),e.onSuccess)}startPlan(e){if(this.destroyed)throw Error(`[CheckoutWidget] cannot start: instance has been destroyed`);if(!e.planId||typeof e.planId!=`string`)throw Error(`[CheckoutWidget] planId is required`);let t=new URL(`/checkout/plan/${encodeURIComponent(e.planId)}`,this.embedBase);this.mount(t,e,t=>({planId:t.planId??e.planId,txHash:t.txHash}),e.onSuccess)}destroy(){this.destroyed=!0,this.manager?.destroy(),this.manager=null}closeFromIframe(e,t){this.destroyed||this.manager!==t||(this.destroy(),e.onClose?.())}buildSuccessHandle(e,t){return{close:()=>this.closeFromIframe(e,t)}}mount(e,t,n,r){this.manager?.destroy();let i=new URL(this.embedBase).origin;e.searchParams.set(`parentOrigin`,window.location.origin),e.searchParams.set(`network`,this.embedNetwork);let a=new S(i);this.manager=a,a.create(e.toString(),{container:t.container,width:t.width,height:t.height}),a.onMessage(e=>this.handleMessage(e,t,a,n,r))}handleMessage(e,t,n,r,i){switch(e.type){case h.BOOTED:this.manager?.postMessage(y(h.INIT,{sessionToken:this.session.getToken()})),t.onBooted?.();return;case h.READY:t.onReady?.();return;case h.SUCCESS:{let a=r(e.payload!=null&&typeof e.payload==`object`?e.payload:{});i?.({result:a,handle:this.buildSuccessHandle(t,n)});return}case h.ERROR:{let n=e.payload;t.onError?.(n?.error??C);return}case h.CLOSE:this.closeFromIframe(t,n);return;default:return}}},T={code:`UNKNOWN`,message:`Unknown widget error`},E={code:`UNKNOWN`,message:`Malformed nvm:success payload — paymentMethodId missing or invalid`},D={code:`UNKNOWN`,message:`Malformed nvm:success payload — delegationId missing or invalid`},O=/^0x[a-fA-F0-9]{40}$/;function k(e){return e&&O.test(e)?`crypto`:`card`}var A=class{session;embedBase;apiBase;embedNetwork;manager=null;destroyed=!1;constructor(e,t,n,r){this.session=e,this.embedBase=t,this.apiBase=n,this.embedNetwork=r}enrollCard(e){this.assertAlive(`enrollCard`);let t=e.provider??`stripe`,n=this.mountIframe(`/cards/enroll`,e.container,{provider:t},{width:e.width,height:e.height});n.onMessage(t=>this.handleEnrollMessage(t,e,n))}listCards(e){this.assertAlive(`listCards`);let t=this.mountIframe(`/cards/list`,e.container,void 0,{width:e.width,height:e.height});t.onMessage(n=>this.handleListMessage(n,e,t))}createDelegation(e){this.assertAlive(`createDelegation`);let t=e.provider??k(e.paymentMethodId);if(t===`card`&&(typeof e.paymentMethodId!=`string`||e.paymentMethodId.length===0))throw Error(`[DelegationsWidget] createDelegation: paymentMethodId is required for provider 'card'`);let n=this.mountIframe(`/cards/delegate`,e.container,{provider:t,...t===`card`&&e.paymentMethodId?{paymentMethodId:e.paymentMethodId}:{}},{width:e.width,height:e.height});n.onMessage(t=>this.handleCreateDelegationMessage(t,e,n))}async revokeCard(e){if(typeof e!=`string`||e.length===0)throw Error(`[DelegationsWidget] revokeCard: paymentMethodId is required`);await this.deleteWithSession(`${this.apiBase}/api/v1/widgets/payment-methods/${encodeURIComponent(e)}`,`Failed to revoke payment method`)}async revokeDelegation(e){if(typeof e!=`string`||e.length===0)throw Error(`[DelegationsWidget] revokeDelegation: delegationId is required`);await this.deleteWithSession(`${this.apiBase}/api/v1/widgets/delegation/${encodeURIComponent(e)}`,`Failed to revoke delegation`)}destroy(){this.destroyed=!0,this.manager?.destroy(),this.manager=null}assertAlive(e){if(this.destroyed)throw Error(`[DelegationsWidget] cannot ${e}: instance has been destroyed`)}mountIframe(e,t,n={},r={}){this.manager?.destroy();let i=new URL(this.embedBase).origin,a=window.location.origin,o=new URL(e,this.embedBase);o.searchParams.set(`parentOrigin`,a),o.searchParams.set(`network`,this.embedNetwork);for(let[e,t]of Object.entries(n))o.searchParams.set(e,t);let s=new S(i);return this.manager=s,s.create(o.toString(),{container:t,width:r.width,height:r.height}),s}postInitOnBooted(){this.manager?.postMessage(y(h.INIT,{sessionToken:this.session.getToken()}))}handleEnrollMessage(e,t,n){switch(e.type){case h.BOOTED:this.postInitOnBooted(),t.onBooted?.();return;case h.READY:t.onReady?.();return;case h.SUCCESS:{let r=(e.payload??{}).paymentMethodId;if(typeof r!=`string`||r.length===0){t.onError?.(E);return}t.onSuccess?.({result:{paymentMethodId:r},handle:this.buildSuccessHandle(t,n)});return}case h.ERROR:{let n=e.payload;t.onError?.(n?.error??T);return}case h.CLOSE:this.closeFromIframe(t,n);return;default:return}}handleListMessage(e,t,n){switch(e.type){case h.BOOTED:this.postInitOnBooted(),t.onBooted?.();return;case h.READY:t.onReady?.();return;case h.CARD_ACTION:{let n=e.payload??{};if(n.action!==`delegate`&&n.action!==`revoked`||typeof n.paymentMethodId!=`string`||n.paymentMethodId.length===0)return;t.onCardAction?.({action:n.action,paymentMethodId:n.paymentMethodId});return}case h.ERROR:{let n=e.payload;t.onError?.(n?.error??T);return}case h.CLOSE:this.closeFromIframe(t,n);return;default:return}}handleCreateDelegationMessage(e,t,n){switch(e.type){case h.BOOTED:this.postInitOnBooted(),t.onBooted?.();return;case h.READY:t.onReady?.();return;case h.SUCCESS:{let r=(e.payload??{}).delegationId;if(typeof r!=`string`||r.length===0){t.onError?.(D);return}t.onSuccess?.({result:{delegationId:r,paymentMethodId:t.paymentMethodId},handle:this.buildSuccessHandle(t,n)});return}case h.ERROR:{let n=e.payload;t.onError?.(n?.error??T);return}case h.CLOSE:this.closeFromIframe(t,n);return;default:return}}closeFromIframe(e,t){this.destroyed||this.manager!==t||(this.destroy(),e.onClose?.())}buildSuccessHandle(e,t){return{close:()=>this.closeFromIframe(e,t)}}async deleteWithSession(e,t){let n;try{n=await fetch(e,{method:`DELETE`,headers:{Authorization:`Bearer ${this.session.getToken()}`,Accept:`application/json`}})}catch(e){throw new d(e instanceof Error&&e.message?e.message:t)}if(n.ok)return;let r,i=t;try{let e=await n.json();typeof e?.message==`string`&&e.message.length>0&&(i=e.message),typeof e?.code==`string`&&(r=e.code)}catch{}throw new d(i,n.status,r)}};function j(e){if(typeof e!=`object`||!e)return!1;let t=e;return[`sessionToken`,`userId`,`expiresAt`,`apiKeyHash`].every(e=>typeof t[e]==`string`)&&typeof t.userWallet==`string`&&t.userWallet.startsWith(`0x`)}var M=class e{sessionManager;_account;environment;_checkout=null;_delegations=null;events=new m;constructor(e,t,n){this.sessionManager=e,this._account=t,this.environment=n}static async initialize(n){let{session:r,environment:i}=n;if(!r||typeof r!=`object`)throw new l(`MISSING_SESSION`);if(!i||!t.includes(i))throw new l(`INVALID_ENVIRONMENT`);if(!j(r))throw new l(`INVALID_SESSION`);let a=new p(r),o=new e(a,{userId:r.userId,userWallet:r.userWallet},i);return a.startAutoRefresh(()=>o.refreshSession(),()=>o.events.emit(`session-expired`,void 0)),o}async refreshSession(){let e=await fetch(`${i(this.environment)}/api/v1/widgets/session/refresh`,{method:`POST`,headers:{Authorization:`Bearer ${this.sessionManager.getToken()}`}});if(!e.ok)throw Error(`Session refresh failed with status ${e.status}`);let t=await e.json();if(!j(t))throw Error(`Session refresh returned an invalid response`);return t}on(e,t){return this.events.on(e,t),this}off(e,t){return this.events.off(e,t),this}get account(){return this._account}get hasValidSession(){return this.sessionManager.isValid()}getSessionToken(){if(!this.sessionManager.isValid())throw new u;return this.sessionManager.getToken()}get checkout(){return this._checkout||=new w(this.sessionManager,a(this.environment),s(this.environment)),this._checkout}get delegations(){return this._delegations||=new A(this.sessionManager,a(this.environment),i(this.environment),s(this.environment)),this._delegations}destroy(){this.sessionManager.stopAutoRefresh(),this._checkout?.destroy(),this._checkout=null,this._delegations?.destroy(),this._delegations=null,this.events.removeAllListeners()}};e.CheckoutWidget=w,e.DelegationsWidget=A,e.IframeManager=S,e.NeverminedWidgets=M,e.SessionManager=p,e.TypedEventEmitter=m,e.WIDGET_MESSAGE_VERSION=g,e.WidgetApiError=d,e.WidgetInitError=l,e.WidgetMessageType=h,e.WidgetSessionExpiredError=u,e.createMessage=y,e.parseMessage=b});
1
+ (function(e,t){typeof exports==`object`&&typeof module<`u`?t(exports):typeof define==`function`&&define.amd?define([`exports`],t):(e=typeof globalThis<`u`?globalThis:e||self,t(e.NeverminedWidgets={}))})(this,function(e){Object.defineProperty(e,Symbol.toStringTag,{value:`Module`});var t=[`local`,`sandbox`,`live`,`staging_sandbox`,`staging_live`],n={local:`http://localhost:3001`,sandbox:`https://api.sandbox.nevermined.app`,live:`https://api.live.nevermined.app`,staging_sandbox:`https://api.sandbox.nevermined.dev`,staging_live:`https://api.live.nevermined.dev`},r={local:`http://localhost:4250`,sandbox:`https://embed.nevermined.app`,live:`https://embed.nevermined.app`,staging_sandbox:`https://embed.nevermined.dev`,staging_live:`https://embed.nevermined.dev`};function i(e){return n[e]}function a(e){return r[e]}var o={local:`sandbox`,sandbox:`sandbox`,live:`live`,staging_sandbox:`sandbox`,staging_live:`live`};function s(e){return o[e]}var c={MISSING_SESSION:{numericCode:`WDG.0001`,message:`session is required — pass the WidgetSession returned by createWidgetSession on the backend`},INVALID_ENVIRONMENT:{numericCode:`WDG.0002`,message:`environment must be one of: sandbox, live, staging_sandbox, staging_live, local`},INVALID_SESSION:{numericCode:`WDG.0003`,message:`session is missing required fields`},SESSION_EXPIRED:{numericCode:`WDG.0006`,message:`Widget session has expired`}},l=class extends Error{code;constructor(e,t,n){super(t??c[e].message,{cause:n}),this.code=e,this.name=`WidgetInitError`}},u=class extends Error{code=`SESSION_EXPIRED`;constructor(){super(c.SESSION_EXPIRED.message),this.name=`WidgetSessionExpiredError`}},d=class extends Error{status;apiCode;constructor(e,t,n){super(e),this.status=t,this.apiCode=n,this.name=`WidgetApiError`}},f=.8,p=class{session;expiresMs;timer=null;constructor(e){this.session=e,this.expiresMs=new Date(e.expiresAt).getTime(),Number.isNaN(this.expiresMs)&&console.warn(`[SessionManager] malformed expiresAt, session will be treated as expired:`,e.expiresAt)}isValid(){return!Number.isNaN(this.expiresMs)&&this.expiresMs>Date.now()}getToken(){return this.session.sessionToken}getSession(){return this.session}startAutoRefresh(e,t){if(this.stopAutoRefresh(),!this.isValid()){t();return}let n=Math.max(0,Math.floor((this.expiresMs-Date.now())*f));this.timer=setTimeout(()=>{this.timer=null,e().then(n=>{if(this.session=n,this.expiresMs=new Date(n.expiresAt).getTime(),!this.isValid()){t();return}this.startAutoRefresh(e,t)},e=>{console.error(`[SessionManager] session refresh failed:`,e),t()})},n)}stopAutoRefresh(){this.timer!==null&&(clearTimeout(this.timer),this.timer=null)}},m=class{listeners=new Map;on(e,t){let n=this.listeners.get(e)??new Set;return n.add(t),this.listeners.set(e,n),this}off(e,t){let n=this.listeners.get(e);return n?(n.delete(t),n.size===0&&this.listeners.delete(e),this):this}once(e,t){let n=r=>{this.off(e,n),t(r)};return this.on(e,n)}removeAllListeners(e){return e===void 0?this.listeners.clear():this.listeners.delete(e),this}emit(e,t){let n=this.listeners.get(e);n&&[...n].forEach(e=>{try{e(t)}catch(e){console.error(`[TypedEventEmitter] Handler threw:`,e)}})}},h=function(e){return e.INIT=`nvm:init`,e.CLOSE=`nvm:close`,e.BOOTED=`nvm:booted`,e.READY=`nvm:ready`,e.RESIZE=`nvm:resize`,e.SUCCESS=`nvm:success`,e.ERROR=`nvm:error`,e.CARD_ACTION=`nvm:card-action`,e}({}),g=`1`,_=`1`;function v(e){return typeof e==`string`&&Object.values(h).includes(e)}function y(e,t){return{type:e,version:_,payload:t}}function b(e){if(typeof e!=`object`||!e)return{ok:!1,reason:`not an object`};let t=e;return v(t.type)?t.version===_?{ok:!0,message:{type:t.type,version:t.version,payload:t.payload}}:{ok:!1,reason:`version mismatch: received "${t.version}", expected "${_}"`}:{ok:!1,reason:typeof t.type==`string`&&t.type.startsWith(`nvm:`)?`unknown nvm: type "${t.type}"`:`missing or unknown type`}}function x(e,t,n){return Math.max(t,Math.min(n,Math.round(e)))}var S=class{expectedOrigin;iframe=null;messageHandlers=new Set;protocolErrorHandlers=new Set;messageListener=null;destroyed=!1;constructor(e){if(this.expectedOrigin=e,e===`*`)throw Error(`[IframeManager] Wildcard origin "*" is not allowed — pass an explicit origin`)}create(e,t){this.iframe?.remove();let n=document.createElement(`iframe`);if(n.src=e,n.style.display=`block`,n.setAttribute(`allow`,`payment *`),n.setAttribute(`sandbox`,`allow-scripts allow-same-origin allow-forms allow-popups allow-popups-to-escape-sandbox allow-top-navigation-by-user-activation`),!t?.container)n.style.width=`100%`,n.style.height=`100%`,n.style.border=`none`,n.style.position=`fixed`,n.style.top=`0`,n.style.left=`0`,n.style.right=`0`,n.style.bottom=`0`,n.style.zIndex=`9999`;else{let e=x(t.width??480,440,720),r=x(t.height??720,640,960);n.style.width=`${e}px`,n.style.height=`${r}px`,n.style.border=`1px solid #e5e7eb`,n.style.borderRadius=`8px`,n.style.boxSizing=`border-box`}return t?.style&&Object.assign(n.style,t.style),(t?.container??document.body).appendChild(n),this.iframe=n,n}destroy(){this.destroyed=!0,this.messageListener&&=(window.removeEventListener(`message`,this.messageListener),null),this.messageHandlers.clear(),this.protocolErrorHandlers.clear(),this.iframe?.remove(),this.iframe=null}postMessage(e){this.destroyed||this.iframe?.contentWindow?.postMessage(e,this.expectedOrigin)}onMessage(e){return this.destroyed?()=>void 0:(this.messageHandlers.add(e),this.ensureListener(),()=>this.messageHandlers.delete(e))}onProtocolError(e){return this.destroyed?()=>void 0:(this.protocolErrorHandlers.add(e),this.ensureListener(),()=>this.protocolErrorHandlers.delete(e))}ensureListener(){this.messageListener||(this.messageListener=e=>{if(e.origin!==this.expectedOrigin)return;let t=b(e.data);if(!t.ok){console.warn(`[IframeManager] Discarding message from ${this.expectedOrigin}: ${t.reason}`),this.protocolErrorHandlers.forEach(e=>{try{e(t.reason)}catch(e){console.error(`[IframeManager] Protocol error handler threw:`,e)}});return}this.messageHandlers.forEach(e=>{try{e(t.message)}catch(e){console.error(`[IframeManager] Message handler threw:`,e)}})},window.addEventListener(`message`,this.messageListener))}},C={code:`UNKNOWN`,message:`Unknown widget error`},w=class{session;embedBase;embedNetwork;manager=null;destroyed=!1;constructor(e,t,n){this.session=e,this.embedBase=t,this.embedNetwork=n}start(e){if(this.destroyed)throw Error(`[CheckoutWidget] cannot start: instance has been destroyed`);if(!e.did||typeof e.did!=`string`)throw Error(`[CheckoutWidget] did is required`);let t=new URL(`/checkout/${encodeURIComponent(e.did)}`,this.embedBase);e.planId&&t.searchParams.set(`planId`,e.planId),this.mount(t,e,t=>({did:t.did??e.did,planId:t.planId??e.planId,txHash:t.txHash}),e.onSuccess)}startPlan(e){if(this.destroyed)throw Error(`[CheckoutWidget] cannot start: instance has been destroyed`);if(!e.planId||typeof e.planId!=`string`)throw Error(`[CheckoutWidget] planId is required`);let t=new URL(`/checkout/plan/${encodeURIComponent(e.planId)}`,this.embedBase);this.mount(t,e,t=>({planId:t.planId??e.planId,txHash:t.txHash}),e.onSuccess)}destroy(){this.destroyed=!0,this.manager?.destroy(),this.manager=null}closeFromIframe(e,t){this.destroyed||this.manager!==t||(this.destroy(),e.onClose?.())}buildSuccessHandle(e,t){return{close:()=>this.closeFromIframe(e,t)}}mount(e,t,n,r){this.manager?.destroy();let i=new URL(this.embedBase).origin;e.searchParams.set(`parentOrigin`,window.location.origin),e.searchParams.set(`network`,this.embedNetwork);let a=new S(i);this.manager=a,a.create(e.toString(),{container:t.container,width:t.width,height:t.height}),a.onMessage(e=>this.handleMessage(e,t,a,n,r))}handleMessage(e,t,n,r,i){switch(e.type){case h.BOOTED:this.manager?.postMessage(y(h.INIT,{sessionToken:this.session.getToken()})),t.onBooted?.();return;case h.READY:t.onReady?.();return;case h.SUCCESS:{let a=r(e.payload!=null&&typeof e.payload==`object`?e.payload:{});i?.({result:a,handle:this.buildSuccessHandle(t,n)});return}case h.ERROR:{let n=e.payload;t.onError?.(n?.error??C);return}case h.CLOSE:this.closeFromIframe(t,n);return;default:return}}},T={code:`UNKNOWN`,message:`Unknown widget error`},E={code:`UNKNOWN`,message:`Malformed nvm:success payload — paymentMethodId missing or invalid`},D={code:`UNKNOWN`,message:`Malformed nvm:success payload — delegationId missing or invalid`},O={code:`UNKNOWN`,message:`Malformed nvm:success payload — paymentMethodId or delegationId missing or invalid`};function k(e){return typeof e==`string`&&e.length>0}var A=/^0x[a-fA-F0-9]{40}$/;function j(e){return e&&A.test(e)?`crypto`:`card`}var M=4096;function N(e,t){if(!t||Object.keys(t).length===0)return{provider:e};let n=JSON.stringify(t);if(n.length>M)throw Error(`[DelegationsWidget] iframeCss is too large (max ${M} bytes once JSON-encoded)`);return{provider:e,iframeCss:n}}var P=class{session;embedBase;apiBase;embedNetwork;manager=null;destroyed=!1;constructor(e,t,n,r){this.session=e,this.embedBase=t,this.apiBase=n,this.embedNetwork=r}enrollCard(e){this.assertAlive(`enrollCard`);let t=e.provider??`stripe`,n=this.mountIframe(`/cards/enroll`,e.container,N(t,e.iframeCss),{width:e.width,height:e.height});n.onMessage(t=>this.handleEnrollMessage(t,e,n))}listCards(e){this.assertAlive(`listCards`);let t=this.mountIframe(`/cards/list`,e.container,void 0,{width:e.width,height:e.height});t.onMessage(n=>this.handleListMessage(n,e,t))}createDelegation(e){this.assertAlive(`createDelegation`);let t=e.provider??j(e.paymentMethodId);if(t===`card`&&(typeof e.paymentMethodId!=`string`||e.paymentMethodId.length===0))throw Error(`[DelegationsWidget] createDelegation: paymentMethodId is required for provider 'card'`);let n=this.mountIframe(`/cards/delegate`,e.container,{provider:t,...t===`card`&&e.paymentMethodId?{paymentMethodId:e.paymentMethodId}:{}},{width:e.width,height:e.height});n.onMessage(t=>this.handleCreateDelegationMessage(t,e,n))}setupCard(e){this.assertAlive(`setupCard`);let t=e.provider??`stripe`,n=this.mountIframe(`/cards/setup`,e.container,N(t,e.iframeCss),{width:e.width,height:e.height});n.onMessage(t=>this.handleSetupMessage(t,e,n))}async revokeCard(e){if(typeof e!=`string`||e.length===0)throw Error(`[DelegationsWidget] revokeCard: paymentMethodId is required`);await this.deleteWithSession(`${this.apiBase}/api/v1/widgets/payment-methods/${encodeURIComponent(e)}`,`Failed to revoke payment method`)}async revokeDelegation(e){if(typeof e!=`string`||e.length===0)throw Error(`[DelegationsWidget] revokeDelegation: delegationId is required`);await this.deleteWithSession(`${this.apiBase}/api/v1/widgets/delegation/${encodeURIComponent(e)}`,`Failed to revoke delegation`)}destroy(){this.destroyed=!0,this.manager?.destroy(),this.manager=null}assertAlive(e){if(this.destroyed)throw Error(`[DelegationsWidget] cannot ${e}: instance has been destroyed`)}mountIframe(e,t,n={},r={}){this.manager?.destroy();let i=new URL(this.embedBase).origin,a=window.location.origin,o=new URL(e,this.embedBase);o.searchParams.set(`parentOrigin`,a),o.searchParams.set(`network`,this.embedNetwork);for(let[e,t]of Object.entries(n))o.searchParams.set(e,t);let s=new S(i);return this.manager=s,s.create(o.toString(),{container:t,width:r.width,height:r.height}),s}postInitOnBooted(){this.manager?.postMessage(y(h.INIT,{sessionToken:this.session.getToken()}))}dispatchLifecycle(e,t,n){switch(e.type){case h.BOOTED:this.postInitOnBooted(),t.onBooted?.();return;case h.READY:t.onReady?.();return;case h.ERROR:{let n=e.payload;t.onError?.(n?.error??T);return}case h.CLOSE:this.closeFromIframe(t,n);return;default:return}}handleEnrollMessage(e,t,n){if(e.type===h.SUCCESS){let r=e.payload??{};if(!k(r.paymentMethodId)){t.onError?.(E);return}t.onSuccess?.({result:{paymentMethodId:r.paymentMethodId},handle:this.buildSuccessHandle(t,n)});return}this.dispatchLifecycle(e,t,n)}handleListMessage(e,t,n){if(e.type===h.CARD_ACTION){let n=e.payload??{};if(n.action!==`delegate`&&n.action!==`revoked`||!k(n.paymentMethodId))return;t.onCardAction?.({action:n.action,paymentMethodId:n.paymentMethodId});return}this.dispatchLifecycle(e,t,n)}handleCreateDelegationMessage(e,t,n){if(e.type===h.SUCCESS){let r=e.payload??{};if(!k(r.delegationId)){t.onError?.(D);return}t.onSuccess?.({result:{delegationId:r.delegationId,paymentMethodId:t.paymentMethodId},handle:this.buildSuccessHandle(t,n)});return}this.dispatchLifecycle(e,t,n)}handleSetupMessage(e,t,n){if(e.type===h.SUCCESS){let r=e.payload??{};if(!k(r.paymentMethodId)||!k(r.delegationId)){t.onError?.(O);return}t.onSuccess?.({result:{paymentMethodId:r.paymentMethodId,delegationId:r.delegationId},handle:this.buildSuccessHandle(t,n)});return}this.dispatchLifecycle(e,t,n)}closeFromIframe(e,t){this.destroyed||this.manager!==t||(this.destroy(),e.onClose?.())}buildSuccessHandle(e,t){return{close:()=>this.closeFromIframe(e,t)}}async deleteWithSession(e,t){let n;try{n=await fetch(e,{method:`DELETE`,headers:{Authorization:`Bearer ${this.session.getToken()}`,Accept:`application/json`}})}catch(e){throw new d(e instanceof Error&&e.message?e.message:t)}if(n.ok)return;let r,i=t;try{let e=await n.json();typeof e?.message==`string`&&e.message.length>0&&(i=e.message),typeof e?.code==`string`&&(r=e.code)}catch{}throw new d(i,n.status,r)}};function F(e){if(typeof e!=`object`||!e)return!1;let t=e;return[`sessionToken`,`userId`,`expiresAt`,`apiKeyHash`].every(e=>typeof t[e]==`string`)&&typeof t.userWallet==`string`&&t.userWallet.startsWith(`0x`)}var I=class e{sessionManager;_account;environment;_checkout=null;_delegations=null;events=new m;constructor(e,t,n){this.sessionManager=e,this._account=t,this.environment=n}static async initialize(n){let{session:r,environment:i}=n;if(!r||typeof r!=`object`)throw new l(`MISSING_SESSION`);if(!i||!t.includes(i))throw new l(`INVALID_ENVIRONMENT`);if(!F(r))throw new l(`INVALID_SESSION`);let a=new p(r),o=new e(a,{userId:r.userId,userWallet:r.userWallet},i);return a.startAutoRefresh(()=>o.refreshSession(),()=>o.events.emit(`session-expired`,void 0)),o}async refreshSession(){let e=await fetch(`${i(this.environment)}/api/v1/widgets/session/refresh`,{method:`POST`,headers:{Authorization:`Bearer ${this.sessionManager.getToken()}`}});if(!e.ok)throw Error(`Session refresh failed with status ${e.status}`);let t=await e.json();if(!F(t))throw Error(`Session refresh returned an invalid response`);return t}on(e,t){return this.events.on(e,t),this}off(e,t){return this.events.off(e,t),this}get account(){return this._account}get hasValidSession(){return this.sessionManager.isValid()}getSessionToken(){if(!this.sessionManager.isValid())throw new u;return this.sessionManager.getToken()}get checkout(){return this._checkout||=new w(this.sessionManager,a(this.environment),s(this.environment)),this._checkout}get delegations(){return this._delegations||=new P(this.sessionManager,a(this.environment),i(this.environment),s(this.environment)),this._delegations}destroy(){this.sessionManager.stopAutoRefresh(),this._checkout?.destroy(),this._checkout=null,this._delegations?.destroy(),this._delegations=null,this.events.removeAllListeners()}};e.CheckoutWidget=w,e.DelegationsWidget=P,e.IframeManager=S,e.NeverminedWidgets=I,e.SessionManager=p,e.TypedEventEmitter=m,e.WIDGET_MESSAGE_VERSION=g,e.WidgetApiError=d,e.WidgetInitError=l,e.WidgetMessageType=h,e.WidgetSessionExpiredError=u,e.createMessage=y,e.parseMessage=b});
package/dist/index.mjs CHANGED
@@ -314,11 +314,28 @@ var x = class {
314
314
  }, E = {
315
315
  code: "UNKNOWN",
316
316
  message: "Malformed nvm:success payload — delegationId missing or invalid"
317
- }, D = /^0x[a-fA-F0-9]{40}$/;
317
+ }, D = {
318
+ code: "UNKNOWN",
319
+ message: "Malformed nvm:success payload — paymentMethodId or delegationId missing or invalid"
320
+ };
318
321
  function O(e) {
319
- return e && D.test(e) ? "crypto" : "card";
322
+ return typeof e == "string" && e.length > 0;
320
323
  }
321
- var k = class {
324
+ var k = /^0x[a-fA-F0-9]{40}$/;
325
+ function A(e) {
326
+ return e && k.test(e) ? "crypto" : "card";
327
+ }
328
+ var j = 4096;
329
+ function M(e, t) {
330
+ if (!t || Object.keys(t).length === 0) return { provider: e };
331
+ let n = JSON.stringify(t);
332
+ if (n.length > j) throw Error(`[DelegationsWidget] iframeCss is too large (max ${j} bytes once JSON-encoded)`);
333
+ return {
334
+ provider: e,
335
+ iframeCss: n
336
+ };
337
+ }
338
+ var N = class {
322
339
  session;
323
340
  embedBase;
324
341
  apiBase;
@@ -330,7 +347,7 @@ var k = class {
330
347
  }
331
348
  enrollCard(e) {
332
349
  this.assertAlive("enrollCard");
333
- let t = e.provider ?? "stripe", n = this.mountIframe("/cards/enroll", e.container, { provider: t }, {
350
+ let t = e.provider ?? "stripe", n = this.mountIframe("/cards/enroll", e.container, M(t, e.iframeCss), {
334
351
  width: e.width,
335
352
  height: e.height
336
353
  });
@@ -346,7 +363,7 @@ var k = class {
346
363
  }
347
364
  createDelegation(e) {
348
365
  this.assertAlive("createDelegation");
349
- let t = e.provider ?? O(e.paymentMethodId);
366
+ let t = e.provider ?? A(e.paymentMethodId);
350
367
  if (t === "card" && (typeof e.paymentMethodId != "string" || e.paymentMethodId.length === 0)) throw Error("[DelegationsWidget] createDelegation: paymentMethodId is required for provider 'card'");
351
368
  let n = this.mountIframe("/cards/delegate", e.container, {
352
369
  provider: t,
@@ -357,6 +374,14 @@ var k = class {
357
374
  });
358
375
  n.onMessage((t) => this.handleCreateDelegationMessage(t, e, n));
359
376
  }
377
+ setupCard(e) {
378
+ this.assertAlive("setupCard");
379
+ let t = e.provider ?? "stripe", n = this.mountIframe("/cards/setup", e.container, M(t, e.iframeCss), {
380
+ width: e.width,
381
+ height: e.height
382
+ });
383
+ n.onMessage((t) => this.handleSetupMessage(t, e, n));
384
+ }
360
385
  async revokeCard(e) {
361
386
  if (typeof e != "string" || e.length === 0) throw Error("[DelegationsWidget] revokeCard: paymentMethodId is required");
362
387
  await this.deleteWithSession(`${this.apiBase}/api/v1/widgets/payment-methods/${encodeURIComponent(e)}`, "Failed to revoke payment method");
@@ -386,7 +411,7 @@ var k = class {
386
411
  postInitOnBooted() {
387
412
  this.manager?.postMessage(v(m.INIT, { sessionToken: this.session.getToken() }));
388
413
  }
389
- handleEnrollMessage(e, t, n) {
414
+ dispatchLifecycle(e, t, n) {
390
415
  switch (e.type) {
391
416
  case m.BOOTED:
392
417
  this.postInitOnBooted(), t.onBooted?.();
@@ -394,18 +419,6 @@ var k = class {
394
419
  case m.READY:
395
420
  t.onReady?.();
396
421
  return;
397
- case m.SUCCESS: {
398
- let r = (e.payload ?? {}).paymentMethodId;
399
- if (typeof r != "string" || r.length === 0) {
400
- t.onError?.(T);
401
- return;
402
- }
403
- t.onSuccess?.({
404
- result: { paymentMethodId: r },
405
- handle: this.buildSuccessHandle(t, n)
406
- });
407
- return;
408
- }
409
422
  case m.ERROR: {
410
423
  let n = e.payload;
411
424
  t.onError?.(n?.error ?? w);
@@ -417,67 +430,68 @@ var k = class {
417
430
  default: return;
418
431
  }
419
432
  }
420
- handleListMessage(e, t, n) {
421
- switch (e.type) {
422
- case m.BOOTED:
423
- this.postInitOnBooted(), t.onBooted?.();
424
- return;
425
- case m.READY:
426
- t.onReady?.();
427
- return;
428
- case m.CARD_ACTION: {
429
- let n = e.payload ?? {};
430
- if (n.action !== "delegate" && n.action !== "revoked" || typeof n.paymentMethodId != "string" || n.paymentMethodId.length === 0) return;
431
- t.onCardAction?.({
432
- action: n.action,
433
- paymentMethodId: n.paymentMethodId
434
- });
435
- return;
436
- }
437
- case m.ERROR: {
438
- let n = e.payload;
439
- t.onError?.(n?.error ?? w);
433
+ handleEnrollMessage(e, t, n) {
434
+ if (e.type === m.SUCCESS) {
435
+ let r = e.payload ?? {};
436
+ if (!O(r.paymentMethodId)) {
437
+ t.onError?.(T);
440
438
  return;
441
439
  }
442
- case m.CLOSE:
443
- this.closeFromIframe(t, n);
444
- return;
445
- default: return;
440
+ t.onSuccess?.({
441
+ result: { paymentMethodId: r.paymentMethodId },
442
+ handle: this.buildSuccessHandle(t, n)
443
+ });
444
+ return;
445
+ }
446
+ this.dispatchLifecycle(e, t, n);
447
+ }
448
+ handleListMessage(e, t, n) {
449
+ if (e.type === m.CARD_ACTION) {
450
+ let n = e.payload ?? {};
451
+ if (n.action !== "delegate" && n.action !== "revoked" || !O(n.paymentMethodId)) return;
452
+ t.onCardAction?.({
453
+ action: n.action,
454
+ paymentMethodId: n.paymentMethodId
455
+ });
456
+ return;
446
457
  }
458
+ this.dispatchLifecycle(e, t, n);
447
459
  }
448
460
  handleCreateDelegationMessage(e, t, n) {
449
- switch (e.type) {
450
- case m.BOOTED:
451
- this.postInitOnBooted(), t.onBooted?.();
452
- return;
453
- case m.READY:
454
- t.onReady?.();
455
- return;
456
- case m.SUCCESS: {
457
- let r = (e.payload ?? {}).delegationId;
458
- if (typeof r != "string" || r.length === 0) {
459
- t.onError?.(E);
460
- return;
461
- }
462
- t.onSuccess?.({
463
- result: {
464
- delegationId: r,
465
- paymentMethodId: t.paymentMethodId
466
- },
467
- handle: this.buildSuccessHandle(t, n)
468
- });
461
+ if (e.type === m.SUCCESS) {
462
+ let r = e.payload ?? {};
463
+ if (!O(r.delegationId)) {
464
+ t.onError?.(E);
469
465
  return;
470
466
  }
471
- case m.ERROR: {
472
- let n = e.payload;
473
- t.onError?.(n?.error ?? w);
467
+ t.onSuccess?.({
468
+ result: {
469
+ delegationId: r.delegationId,
470
+ paymentMethodId: t.paymentMethodId
471
+ },
472
+ handle: this.buildSuccessHandle(t, n)
473
+ });
474
+ return;
475
+ }
476
+ this.dispatchLifecycle(e, t, n);
477
+ }
478
+ handleSetupMessage(e, t, n) {
479
+ if (e.type === m.SUCCESS) {
480
+ let r = e.payload ?? {};
481
+ if (!O(r.paymentMethodId) || !O(r.delegationId)) {
482
+ t.onError?.(D);
474
483
  return;
475
484
  }
476
- case m.CLOSE:
477
- this.closeFromIframe(t, n);
478
- return;
479
- default: return;
485
+ t.onSuccess?.({
486
+ result: {
487
+ paymentMethodId: r.paymentMethodId,
488
+ delegationId: r.delegationId
489
+ },
490
+ handle: this.buildSuccessHandle(t, n)
491
+ });
492
+ return;
480
493
  }
494
+ this.dispatchLifecycle(e, t, n);
481
495
  }
482
496
  closeFromIframe(e, t) {
483
497
  this.destroyed || this.manager !== t || (this.destroy(), e.onClose?.());
@@ -509,7 +523,7 @@ var k = class {
509
523
  };
510
524
  //#endregion
511
525
  //#region src/nevermined-widgets.ts
512
- function A(e) {
526
+ function P(e) {
513
527
  if (typeof e != "object" || !e) return !1;
514
528
  let t = e;
515
529
  return [
@@ -519,7 +533,7 @@ function A(e) {
519
533
  "apiKeyHash"
520
534
  ].every((e) => typeof t[e] == "string") && typeof t.userWallet == "string" && t.userWallet.startsWith("0x");
521
535
  }
522
- var j = class t {
536
+ var F = class t {
523
537
  sessionManager;
524
538
  _account;
525
539
  environment;
@@ -533,7 +547,7 @@ var j = class t {
533
547
  let { session: r, environment: i } = n;
534
548
  if (!r || typeof r != "object") throw new c("MISSING_SESSION");
535
549
  if (!i || !e.includes(i)) throw new c("INVALID_ENVIRONMENT");
536
- if (!A(r)) throw new c("INVALID_SESSION");
550
+ if (!P(r)) throw new c("INVALID_SESSION");
537
551
  let a = new f(r), o = new t(a, {
538
552
  userId: r.userId,
539
553
  userWallet: r.userWallet
@@ -547,7 +561,7 @@ var j = class t {
547
561
  });
548
562
  if (!e.ok) throw Error(`Session refresh failed with status ${e.status}`);
549
563
  let t = await e.json();
550
- if (!A(t)) throw Error("Session refresh returned an invalid response");
564
+ if (!P(t)) throw Error("Session refresh returned an invalid response");
551
565
  return t;
552
566
  }
553
567
  on(e, t) {
@@ -570,11 +584,11 @@ var j = class t {
570
584
  return this._checkout ||= new C(this.sessionManager, i(this.environment), o(this.environment)), this._checkout;
571
585
  }
572
586
  get delegations() {
573
- return this._delegations ||= new k(this.sessionManager, i(this.environment), r(this.environment), o(this.environment)), this._delegations;
587
+ return this._delegations ||= new N(this.sessionManager, i(this.environment), r(this.environment), o(this.environment)), this._delegations;
574
588
  }
575
589
  destroy() {
576
590
  this.sessionManager.stopAutoRefresh(), this._checkout?.destroy(), this._checkout = null, this._delegations?.destroy(), this._delegations = null, this.events.removeAllListeners();
577
591
  }
578
592
  };
579
593
  //#endregion
580
- export { C as CheckoutWidget, k as DelegationsWidget, x as IframeManager, j as NeverminedWidgets, f as SessionManager, p as TypedEventEmitter, h as WIDGET_MESSAGE_VERSION, u as WidgetApiError, c as WidgetInitError, m as WidgetMessageType, l as WidgetSessionExpiredError, v as createMessage, y as parseMessage };
594
+ export { C as CheckoutWidget, N as DelegationsWidget, x as IframeManager, F as NeverminedWidgets, f as SessionManager, p as TypedEventEmitter, h as WIDGET_MESSAGE_VERSION, u as WidgetApiError, c as WidgetInitError, m as WidgetMessageType, l as WidgetSessionExpiredError, v as createMessage, y as parseMessage };
@@ -15,6 +15,17 @@ export interface EnrollCardResult {
15
15
  * `http://localhost`) cannot embed this provider.
16
16
  */
17
17
  export type EnrollCardProvider = 'stripe' | 'braintree' | 'visa';
18
+ /**
19
+ * Per-field css override for the VGS Collect inputs of the Visa enrolment
20
+ * form (#2018). A plain style object forwarded verbatim to VGS Collect's
21
+ * field `css` option (e.g. `{ 'font-family': '…', color: '#111' }`), shallow-
22
+ * merged over the embed's defaults so an integrator overrides only what they
23
+ * set — nested keys (e.g. `&::placeholder`) are replaced wholesale, not
24
+ * deep-merged. Currently applies to the `'visa'` provider only — Stripe/
25
+ * Braintree use their own theming APIs. Passed to the iframe as a JSON search
26
+ * param (≤4096 bytes once encoded; the SDK throws above that).
27
+ */
28
+ export type WidgetIframeCss = Record<string, unknown>;
18
29
  export interface EnrollCardOptions {
19
30
  container?: HTMLElement;
20
31
  /** See `CheckoutOptions.width`. */
@@ -23,6 +34,8 @@ export interface EnrollCardOptions {
23
34
  height?: number;
24
35
  /** See `EnrollCardProvider`. Defaults to `'stripe'`. */
25
36
  provider?: EnrollCardProvider;
37
+ /** See `WidgetIframeCss` — Visa/VGS field theming. */
38
+ iframeCss?: WidgetIframeCss;
26
39
  onBooted?: () => void;
27
40
  onReady?: () => void;
28
41
  /** See `CheckoutOptions.onSuccess`. */
@@ -83,6 +96,32 @@ export interface CreateDelegationOptions {
83
96
  onError?: (error: EmbedError) => void;
84
97
  onClose?: () => void;
85
98
  }
99
+ /**
100
+ * Combined "enrol a card + set its delegation budget" flow (#2018). Mounts the
101
+ * embed's `/cards/setup` page, which chains the per-provider enrol form into
102
+ * the delegation form and emits one terminal `nvm:success` carrying both ids.
103
+ */
104
+ export interface SetupCardResult {
105
+ paymentMethodId: string;
106
+ delegationId: string;
107
+ }
108
+ export interface SetupCardOptions {
109
+ container?: HTMLElement;
110
+ /** See `CheckoutOptions.width`. */
111
+ width?: number;
112
+ /** See `CheckoutOptions.height`. */
113
+ height?: number;
114
+ /** Card-enrolment provider for the first step. Defaults to `'stripe'`. */
115
+ provider?: EnrollCardProvider;
116
+ /** See `WidgetIframeCss` — Visa/VGS field theming for the enrol step. */
117
+ iframeCss?: WidgetIframeCss;
118
+ onBooted?: () => void;
119
+ onReady?: () => void;
120
+ /** See `CheckoutOptions.onSuccess`. */
121
+ onSuccess?: (event: WidgetSuccessEvent<SetupCardResult>) => void;
122
+ onError?: (error: EmbedError) => void;
123
+ onClose?: () => void;
124
+ }
86
125
  /**
87
126
  * Card and delegation management widget.
88
127
  *
@@ -137,6 +176,15 @@ export declare class DelegationsWidget {
137
176
  * always forwarded as a search param so the form builds the correct payload.
138
177
  */
139
178
  createDelegation(options: CreateDelegationOptions): void;
179
+ /**
180
+ * Mounts the combined enrol-card → create-delegation flow at `/cards/setup`.
181
+ * The embed page chains the per-provider enrol form into the delegation form
182
+ * and emits a single terminal `nvm:success` carrying both `paymentMethodId`
183
+ * and `delegationId`, so the integrator gets both ids from one callback
184
+ * instead of wiring `enrollCard` → `createDelegation` themselves. Same
185
+ * lifecycle / teardown semantics as the other iframe flows.
186
+ */
187
+ setupCard(options: SetupCardOptions): void;
140
188
  /**
141
189
  * Revoke (detach) a payment method via the widget-prefixed API endpoint.
142
190
  * Resolves on 2xx; throws `WidgetApiError` on any other response or
@@ -153,9 +201,18 @@ export declare class DelegationsWidget {
153
201
  private assertAlive;
154
202
  private mountIframe;
155
203
  private postInitOnBooted;
204
+ /**
205
+ * Shared BOOTED / READY / ERROR / CLOSE / (default) handling for every iframe
206
+ * flow. Each `handle*Message` first handles its own message (SUCCESS or
207
+ * CARD_ACTION) and delegates everything else here, so a new lifecycle message
208
+ * is a one-place edit instead of four. Typed structurally — it only touches
209
+ * the lifecycle callbacks every options shape shares.
210
+ */
211
+ private dispatchLifecycle;
156
212
  private handleEnrollMessage;
157
213
  private handleListMessage;
158
214
  private handleCreateDelegationMessage;
215
+ private handleSetupMessage;
159
216
  /**
160
217
  * #1668: shared close path for `handle.close()` (integrator-driven) and
161
218
  * `nvm:close` (iframe-driven). Idempotent so a race between the
@@ -1 +1 @@
1
- {"version":3,"file":"delegations.d.ts","sourceRoot":"","sources":["../../src/widgets/delegations.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"delegations.d.ts","sourceRoot":"","sources":["../../src/widgets/delegations.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nevermined-io/ui-widgets",
3
- "version": "1.2.1",
3
+ "version": "1.2.2",
4
4
  "type": "module",
5
5
  "main": "./dist/index.js",
6
6
  "module": "./dist/index.mjs",