@cantor8/wallet-connect-sdk 0.5.0 → 0.6.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -62,6 +62,11 @@ console.log("Accounts", accounts);
62
62
 
63
63
  const senderPartyId = accounts.accounts[0]?.partyId;
64
64
 
65
+ // Registration and validator-managed contract setup state
66
+ // Return type: RegisterStatusResponse
67
+ const contractsSetupState = await c8.getContractsSetupState();
68
+ console.log("Contracts setup state", contractsSetupState);
69
+
65
70
  const senderHoldingInstrumentId =
66
71
  accounts.accounts[0]?.holdings[0]?.instrumentId || firstInstrumentId;
67
72
 
@@ -128,7 +133,9 @@ console.log("Signature", signature);
128
133
  | `connect()` | None | `Promise<void>` |
129
134
  | `disconnect()` | None | `Promise<void>` |
130
135
  | `status()` | None | `Promise<{ connected: boolean; walletVersion?: string }>` |
136
+ | `getContractsSetupState()` | None | `Promise<RegisterStatusResponse>` |
131
137
  | `getInstruments()` | None | `Promise<InstrumentListPayload>` |
138
+ | `getActiveContracts()` | `input?: GetActiveContractsInput` | `Promise<ActiveContractsPayload>` |
132
139
  | `getAccounts()` | `instrumentId?: string` | `Promise<AccountListPayload>` |
133
140
  | `send()` | `input: SendInput` | `Promise<SubmitTransferResultPayload>` |
134
141
  | `createSwapOffer()` | `input: { partyId, swap, commandId? }` | `Promise<SubmitTransferResultPayload>` |
@@ -137,6 +144,65 @@ console.log("Signature", signature);
137
144
  | `checkTxStatusById()` | `input: { txId: string }` | `Promise<TransferStatusResponsePayload>` |
138
145
  | `on()` | `event: T, cb: Listener<C8EventByType<T>>` | `() => boolean` |
139
146
 
147
+ ### `getContractsSetupState()`
148
+
149
+ Returns the current account's registration, confirmation, and validator-managed
150
+ contract setup state:
151
+
152
+ ```ts
153
+ const state = await c8.getContractsSetupState();
154
+
155
+ if (state.isRegistered && state.isConfirmed) {
156
+ console.log("Preapproval ready:", state.isPreapprovalSet);
157
+ console.log("Auto-accept ready:", state.isAutoAcceptSet);
158
+ console.log("USDC bridge ready:", state.isUsdcBridgeSet);
159
+ console.log(
160
+ "Withdrawal delegation ready:",
161
+ state.isWithdrawalDelegationSet,
162
+ );
163
+ console.log("Merge delegation ready:", state.isMergeDelegationSet);
164
+ }
165
+ ```
166
+
167
+ The returned `RegisterStatusResponse` also includes an in-progress flag for each
168
+ contract setup operation: `isPreapprovalInProgress`,
169
+ `isAutoAcceptInProgress`, `isUsdcBridgeSetupInProgress`,
170
+ `isWithdrawalDelegationInProgress`, and `isMergeDelegationInProgress`.
171
+
172
+ ### `getActiveContracts()`
173
+
174
+ Reads Scanner ACS using the Wallet App's authenticated account:
175
+
176
+ ```ts
177
+ const contracts = await c8.getActiveContracts({
178
+ templateIds: ["package-id:Module:Template"],
179
+ includeCreatedEventBlob: true,
180
+ limit: 10000,
181
+ });
182
+ console.log(contracts);
183
+ ```
184
+
185
+ For direct popup-provider reads, optional `partyId` must match the connected primary
186
+ account; the stored token belongs to that account. Embedded Wallet App reads can
187
+ select an account owned by the wallet. The primary account is used by default.
188
+ `interfaceIds` filters interfaces. `activeAtOffset` requests a
189
+ point-in-time snapshot using a nonnegative signed 64-bit decimal **string**.
190
+ Offsets beyond Scanner ingestion are rejected. `limit` must be a positive integer
191
+ and defaults to 10000. `paginated` defaults to `true` so the first page is ordered
192
+ by `contract_id` even when `after` is absent. Pass a nonempty `after` contract ID
193
+ unchanged to request rows after it; explicit `paginated: false` is also forwarded.
194
+ Scanner returns at most `limit` rows without completeness metadata. Base contract
195
+ and interface rows can share a `contract_id`; if the limit splits that group,
196
+ the next `after` request skips its remaining rows. These parameters do not
197
+ guarantee complete traversal.
198
+
199
+ The result is the Scanner contract array with its original field names and
200
+ created-event blobs. JSON numbers use normal JavaScript numeric precision.
201
+ After `connect()`, the popup provider calls the primary account's Scanner endpoint
202
+ directly with the stored wallet token, even after the popup closes. No additional
203
+ token is supplied to this method. Older sessions missing `validator.scannerApiUrl`
204
+ must disconnect and reconnect. Embedded providers retain the existing Wallet App RPC.
205
+
140
206
  ### `send()` Input
141
207
 
142
208
  ```ts
@@ -249,3 +315,37 @@ unsubscribe();
249
315
  ## License
250
316
 
251
317
  MIT
318
+
319
+ ### Ledger updates
320
+
321
+ `getLedgerUpdates` reads one page from Scanner's authenticated `/ledger-nodes`
322
+ feed. External providers use direct HTTP with the stored session token and the
323
+ primary account’s configured Scanner URL, including after the wallet popup closes.
324
+ Embedded providers use the existing App RPC and can select another owned account.
325
+ Like ACS, old sessions without Scanner metadata must disconnect and reconnect.
326
+
327
+ ```ts
328
+ const page = await provider.getLedgerUpdates({
329
+ partyId, // optional; defaults to the primary wallet account
330
+ templateIds: ["package:Module:Template"],
331
+ limit: 500, // 1–1000
332
+ });
333
+ const nextPage = page.nextCursor
334
+ ? await provider.getLedgerUpdates({ partyId, cursor: page.nextCursor,
335
+ templateIds: ["package:Module:Template"] })
336
+ : undefined;
337
+ ```
338
+
339
+ The result is Scanner's `{ nodes, nextCursor?, bounds?, gap?, complete }` page,
340
+ with typed `LedgerNode` fields and unchanged JSON event payloads. Optional `eventType` (`created` or `exercised`) and
341
+ `consuming` filters pass through. Reuse `nextCursor` verbatim with the same
342
+ filters: it retains exact offsets even beyond JavaScript's safe integer range.
343
+ To start at an offset, use `"<offset>:-2147483648"`. Other numeric JSON fields
344
+ have ordinary JavaScript precision.
345
+
346
+ An empty page can still advance the cursor. `complete` means the current Scanner
347
+ fetch frontier was reached; new updates may arrive later. `gap` reports lost
348
+ history and must not be treated as an empty successful history. Requests before
349
+ retained history fail. This is a paginated Scanner feed, not Ledger's streaming
350
+ `/v2/updates` response. Scanner must enable this feed and support user-token party
351
+ authorization (PR #125); the Wallet App must support the new RPC.
package/dist/index.cjs CHANGED
@@ -1 +1 @@
1
- "use strict";const e="cantor8.tech",t="https://wallet.dev.digik.cantor8.tech",s="https://wallet-backend.dev.digik.cantor8.tech",n="https://wallet.cantor8.tech",i="https://wallet.main.digik.cantor8.tech";class r{static getItem(e){try{const t=localStorage.getItem(e);return t?JSON.parse(t):null}catch(e){return null}}static setItem(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(e){}}static removeItem(e){try{localStorage.removeItem(e)}catch(e){}}}const a={TestCoin1:"TestCoin1",Amulet:"Canton Coin",CBTC:"CBTC",USDCx:"USDCx",CETH:"CETH"},o=e=>{var t;return"Amulet"===e?"Canton Coin":null!=(t=a[null!=e?e:""])?t:e},h={TestCoin1:"TestCoin1",Amulet:"CC",CBTC:"CBTC",USDCx:"USDCx"},d=e=>{var t;return"Amulet"===e?"CC":null!=(t=h[null!=e?e:""])?t:e};var c=Object.defineProperty,l=(e,t,s)=>((e,t,s)=>t in e?c(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const u=class e{constructor(){l(this,"appName"),l(this,"accounts",[]),l(this,"instruments",[]),l(this,"authToken",null),l(this,"isConnected",!1),l(this,"expireAt",null),l(this,"disconnectTimeoutId",null),this.load()}static getInstance(){return e.instance||(e.instance=new e),e.instance}setAppName(e){this.appName=e}getAppName(){return this.appName}setInstruments(e){this.instruments=e}getInstruments(){return this.instruments}setAccounts(e){this.accounts=e,this.instruments=e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:o(e.instrumentId),symbol:d(e.instrumentId)})))}getAccounts(){return this.accounts}setBearerToken(e,t){this.authToken=e,this.isConnected=!0,this.expireAt=t}getExpireAt(){return this.expireAt}setDisconnectTimeoutId(e){this.disconnectTimeoutId&&clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=e}getDisconnectTimeoutId(){return this.disconnectTimeoutId}getBearerToken(){return this.authToken}clear(){this.accounts=[],this.instruments=[],this.authToken=null,this.isConnected=!1,this.expireAt=null,this.disconnectTimeoutId&&(clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=null),r.removeItem(e.SESSION_KEY)}save(){r.setItem(e.SESSION_KEY,{authToken:this.authToken,accounts:this.accounts.map(({accountName:e,partyId:t,publicKey:s,validator:n})=>({accountName:e,partyId:t,publicKey:s,validator:n})),expireAt:this.expireAt})}setConnected(e){this.isConnected=e}getConnected(){return this.isConnected}hasStoredSession(){return!!r.getItem(e.SESSION_KEY)}load(){const t=r.getItem(e.SESSION_KEY);t&&(this.authToken=t.authToken,this.accounts=(t.accounts||[]).filter(e=>!!e.validator).map(e=>({...e,holdings:[]})),this.expireAt=t.expireAt||null)}};l(u,"instance"),l(u,"SESSION_KEY","c8-session");let p=u;var g=Object.defineProperty,m=(e,t,s)=>((e,t,s)=>t in e?g(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const f=class e{constructor(e=5e3){this.pollingInterval=e,m(this,"events",new Map),m(this,"intervals",new Map),m(this,"handlerRegistry",new Map),this.restore()}static getInstance(t=5e3){return e.instance||(e.instance=new e(t)),e.instance}registerHandler(e,t){this.handlerRegistry.set(e,t),this.events.forEach((s,n)=>{s.event.type===e&&(this.stopPolling(n),s.handler=t,this.startPolling(n))})}add(e,t){const s=btoa(`${e}-${JSON.stringify(t)}`);this.events.has(s)&&this.remove(s);const n=this.handlerRegistry.get(e);if(!n)return;const i={key:s,type:e,params:t,createdAt:Date.now()};this.events.set(s,{event:i,handler:n}),this.persist(),this.startPolling(s)}remove(e){this.stopPolling(e),this.events.delete(e),this.persist()}startPolling(t){const s=this.events.get(t);if(!s)return;const{event:n,handler:i}=s,r=async()=>{try{if(n.createdAt&&Date.now()-n.createdAt>e.POLLING_TIMEOUT)return void this.remove(t);await i(n.params)&&this.remove(t)}catch(e){}};r();const a=window.setInterval(r,this.pollingInterval);this.intervals.set(t,a)}stopPolling(e){const t=this.intervals.get(e);void 0!==t&&(window.clearInterval(t),this.intervals.delete(e))}persist(){const t=Array.from(this.events.values()).map(e=>e.event);r.setItem(e.STORAGE_KEY,t)}restore(){const t=r.getItem(e.STORAGE_KEY);if(t&&Array.isArray(t)){const s=Date.now();t.forEach(t=>{if(t.createdAt&&s-t.createdAt>e.POLLING_TIMEOUT)return;const n=this.handlerRegistry.get(t.key);n?(this.events.set(t.key,{event:t,handler:n}),this.startPolling(t.key)):this.events.set(t.key,{event:t,handler:async()=>!1})})}}clear(){this.events.clear(),this.intervals.forEach(e=>window.clearInterval(e)),this.intervals.clear(),this.persist(),r.removeItem(e.STORAGE_KEY)}getEvents(){return Array.from(this.events.values()).map(e=>e.event)}};m(f,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),m(f,"type"),m(f,"instance"),m(f,"STORAGE_KEY","c8-polling-events"),m(f,"POLLING_TIMEOUT",3e5);let v=f;var w=Object.defineProperty;class T{constructor(e){((e,t,s)=>{((e,t,s)=>{t in e?w(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s})(e,t+"",s)})(this,"baseUrl"),this.baseUrl=e.endsWith("/")?e.slice(0,-1):e}async request(e,t={}){const s=p.getInstance().getBearerToken(),n=p.getInstance().getAppName(),i=new Headers(t.headers);s&&(i.set("Authorization",`Bearer ${s}`),i.set("X-App-Name",null!=n?n:"Unknown App")),i.set("x-feat-decimals","1");const r=await fetch(`${this.baseUrl}${e}`,{...t,headers:i});if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);return await r.json()}async getBalance(){return this.request("/api/balance")}async getTransferStatus(e){return this.request(`/api/transfer/status?command_id=${e}`)}}var y=Object.defineProperty,k=(e,t,s)=>((e,t,s)=>t in e?y(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function I(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class E{constructor(e,r,a=t){let o;switch(this.appName=e,this.appUrl=r,this.origin=a,k(this,"WINDOW_NAME","c8-wallet"),k(this,"WINDOW_WIDTH",475),k(this,"WINDOW_HEIGHT",762),k(this,"popup"),k(this,"sessionId",crypto.randomUUID()),k(this,"listening",!1),k(this,"walletReady",!1),k(this,"pending",new Map),k(this,"eventHandlers",new Set),k(this,"handshakeTimer"),k(this,"handshakeDeadline"),k(this,"closeWatcherTimer"),k(this,"pollingManager",v.getInstance()),k(this,"session",p.getInstance()),k(this,"initDeferred"),k(this,"httpClient"),this.onWindowMessage=this.onWindowMessage.bind(this),this.handleRestoreSession=this.handleRestoreSession.bind(this),this.handleTrackTxStatus=this.handleTrackTxStatus.bind(this),this.handleAccountUpdate=this.handleAccountUpdate.bind(this),this.session.setAppName(this.appName),this.attachListener(),this.origin){case t:o=s;break;case n:case i:o="https://wallet-backend.main.cantor8.tech";break;default:o=s}this.httpClient=new T(o),this.pollingManager.registerHandler(v.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(v.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(v.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){this.session.hasStoredSession()&&this.pollingManager.add(v.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=this.session.getAccounts().find(t=>t.partyId===e.party_id);if(!t)return!1;const s=[{accountName:t.accountName,partyId:e.party_id,publicKey:t.publicKey,validator:t.validator,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(s),this.session.save()}return!0}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}async getTransferStatusById(e){try{const t=await this.httpClient.getTransferStatus(e);let s;switch(t.status){case"success":s="confirmed";break;case"failed":s="failed";break;default:s="pending"}return t.status=s,t}catch(e){return e instanceof Error&&e.message.includes("401")&&this.destroy(),null}}async handleTrackTxStatus(e){try{const t=await this.httpClient.getTransferStatus(e.txId);if(e.status!==t.status){let s;switch(t.status){case"success":s="confirmed";break;case"failed":s="failed";break;default:s="pending"}return this.emitSyntheticEvent({type:"txChanged",txId:e.txId,status:s}),e.status=t.status,this.pollingManager.persist(),"pending"!==t.status&&this.pollingManager.add(v.EVENT_TYPES.UPDATE_ACCOUNT,{txId:e.txId}),"success"===t.status||"failed"===t.status}}catch(t){if(t instanceof Error&&(t.message.includes("401")&&this.destroy(),t.message.includes("404")))return this.emitSyntheticEvent({type:"txChanged",txId:e.txId,status:"failed"}),!0}return!1}async handleRestoreSession(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=this.session.getAccounts().find(t=>t.partyId===e.party_id);if(!t)return!1;const s=[{accountName:t.accountName,partyId:e.party_id,publicKey:t.publicKey,validator:t.validator,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(s),this.session.save(),this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const n=this.session.getExpireAt();return n&&this.scheduleDisconnect(n),!0}}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}get WALLET_EMBEDDED(){return`${this.origin}/embedded/`}async init(e){var t;if(void 0!==this.popup&&(null==(t=this.popup)||!t.closed))return;if(this.initDeferred||(this.initDeferred=I()),this.listening||this.attachListener(),this.popup&&!this.popup.closed)return this.popup.focus(),null==this.handshakeTimer&&this.startHandshakeLoop(),this.initDeferred.promise;const s=new URL(null!=e?e:"",this.WALLET_EMBEDDED);if(this.popup=window.open(s,this.WINDOW_NAME,`width=${this.WINDOW_WIDTH},height=${this.WINDOW_HEIGHT}`),!this.popup){const e=new Error("Failed to open popup window");Object.assign(e,{code:"POPUP_BLOCKED",message:"browser blocked the popup window"}),this.rejectInit(e)}return this.startHandshakeLoop(),this.initDeferred.promise}emitSyntheticEvent(e){for(const t of this.eventHandlers)try{t({kind:"event",event:e})}catch(e){}}scheduleDisconnect(e){if(!e)return;const t=e-Date.now();if(t>0){const e=setTimeout(()=>{this.destroy("authToken expired")},t);this.session.setDisconnectTimeoutId(e)}else this.destroy("authToken expired")}destroy(e="destroyed"){try{this.emitSyntheticEvent({type:"disconnected",reason:e}),this.detachListener(),this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.reject(new Error("Transport destroyed")),this.initDeferred=void 0);for(const[,e]of this.pending)e.reject(new Error("Transport destroyed"));this.pending.clear(),this.popup&&!this.popup.closed&&this.popup.close(),this.popup=void 0,this.walletReady=!1,this.session.clear(),this.pollingManager.clear()}catch(e){}}async request(e,t,s){var n,i,r,a,o,h,d,c,l,u,p,g,m,f,v,w;const T=crypto.randomUUID(),y=I();this.pending.set(T,y);try{if("connect"===e){if(this.session.getBearerToken())return this.handleResponse({kind:"response",id:T,result:null}),y.promise;this.session.getBearerToken()||(this.walletReady=!1),await this.init()}if("send"===e&&(this.walletReady=!1,await this.init("confirmTransaction")),"createSwapOffer"===e&&(this.walletReady=!1,await this.init("confirmSwapOffer")),"signMessage"===e&&(this.walletReady=!1,await this.init("confirmSignMessage")),"signAndExecute"===e&&(this.walletReady=!1,await this.init("signAndExecute")),"status"===e)return this.handleResponse({kind:"response",id:T,result:{connected:this.session.getConnected(),walletVersion:void 0}}),y.promise;if(s&&(null==(n=this.popup)||n.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:T,result:{instruments:e}}),y.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:T,result:{accounts:e}}),y.promise}if("checkTxStatusById"===e){const e=t,s=await this.getTransferStatusById(null==e?void 0:e.txId);if(s){const e={status:s.status,transfer:{senderPartyId:null!=(r=null==(i=s.transfer)?void 0:i.party_id)?r:"",receiverPartyId:null!=(o=null==(a=s.transfer)?void 0:a.party_id2)?o:"",amount:Number(null!=(d=null==(h=s.transfer)?void 0:h.amount)?d:"0"),networkFees:Number(null!=(l=null==(c=s.transfer)?void 0:c.network_fees)?l:"0"),instrumentId:null!=(p=null==(u=s.transfer)?void 0:u.instrument_id)?p:"",txId:null!=(m=null==(g=s.transfer)?void 0:g.command_id)?m:"",created_at:null!=(v=null==(f=s.transfer)?void 0:f.created_at)?v:"",memo:null==(w=s.transfer)?void 0:w.reason}};this.handleResponse({kind:"response",id:T,result:e})}else this.handleResponse({kind:"response",id:T,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return y.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:T,result:null}),y.promise;const k={kind:"request",id:T,method:e,params:t,sessionId:this.sessionId};this.post(k)}catch(e){this.pending.delete(T),y.reject(e)}return y.promise}onEvent(e){return this.eventHandlers.add(e),()=>{this.eventHandlers.delete(e)}}attachListener(){this.listening||(window.addEventListener("message",this.onWindowMessage),this.listening=!0)}detachListener(){this.listening&&(window.removeEventListener("message",this.onWindowMessage),this.listening=!1)}post(e){try{if(!this.popup||this.popup.closed)return;this.popup.postMessage(e,this.origin)}catch(e){}}onWindowMessage(e){if(e.origin!==this.origin)return;const t=e.data;if(t&&"object"==typeof t){if("event"===t.kind){for(const e of this.eventHandlers)"txInitiated"===t.event.type&&this.pollingManager.add(v.EVENT_TYPES.TRACK_TX_STATUS,{txId:t.event.txId,status:"initiated"}),e(t);return}if("internal_event"===t.kind)return void this.pollingManager.add(t.event.type,{wop:"wopwop"});if("auth-flow"===t.kind&&(this.session.setBearerToken(t.token,t.expireAt),this.session.setAccounts(t.accounts),this.session.setInstruments(t.instruments),this.session.save(),this.scheduleDisconnect(t.expireAt)),"handshake-ack"===t.kind&&t.ok)return void this.handleHandshakeAck();"response"===t.kind&&this.handleResponse(t)}}handleHandshakeAck(){this.walletReady=!0,this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.resolve(),this.initDeferred=void 0)}handleResponse(e){const t=this.pending.get(e.id);if(t)if(this.pending.delete(e.id),e.error){const s=new Error(e.error.message||"Unknown Error");Object.assign(s,{code:e.error.code,data:e.error.data}),t.reject(s)}else t.resolve(e.result)}startHandshakeLoop(){this.handshakeDeadline=Date.now()+55e3;const e=()=>{if(!this.walletReady)return!this.popup||this.popup.closed?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Popup closed before handshake"))):this.handshakeDeadline&&Date.now()>this.handshakeDeadline?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Handshake timed out"))):void this.post({kind:"handshake",sdkVersion:"0.0.0",sessionId:this.sessionId,dapp:{name:this.appName,url:this.appUrl}});this.clearHandshakeLoop()};e(),this.handshakeTimer=window.setInterval(e,300)}clearHandshakeLoop(){null!=this.handshakeTimer&&(clearInterval(this.handshakeTimer),this.handshakeTimer=void 0),this.handshakeDeadline=void 0}rejectInit(e){this.initDeferred&&(Object.assign(e,{code:"INITIALIZATION_FAILED",message:e.message}),this.initDeferred.reject(e),this.initDeferred=void 0)}startPopupClosedWatcher(){const e=this.popup;if(!e)return;const t=window.setInterval(()=>{(!e||e.closed)&&(clearInterval(t),this.destroy())},300);this.closeWatcherTimer=t}}var S=Object.defineProperty,A=(e,t,s)=>((e,t,s)=>t in e?S(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function b(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class D{constructor(e,t,s,n){this.appName=e,this.appUrl=t,this.targetOrigin=s,this.targetWindow=n,A(this,"sessionId",crypto.randomUUID()),A(this,"listening",!1),A(this,"walletReady",!1),A(this,"pending",new Map),A(this,"eventHandlers",new Set),A(this,"handshakeTimer"),A(this,"handshakeDeadline"),A(this,"initDeferred"),this.onWindowMessage=this.onWindowMessage.bind(this),this.attachListener()}async init(){if(!this.walletReady){if(this.initDeferred||(this.initDeferred=b()),this.listening||this.attachListener(),!this.targetWindow){const e=new Error("ThinTransport targetWindow is not available");throw this.rejectInit(e),e}return!this.walletReady&&null==this.handshakeTimer&&this.startHandshakeLoop(),this.initDeferred.promise}}destroy(){try{for(const e of this.eventHandlers)try{e({kind:"event",event:{type:"disconnected",reason:"destroyed"}})}catch{}this.detachListener(),this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.reject(new Error("Transport destroyed")),this.initDeferred=void 0);for(const[,e]of this.pending)e.reject(new Error("Transport destroyed"));this.pending.clear(),this.walletReady=!1}catch(e){}}async request(e,t,s){if("connect"===e&&await this.init(),!this.targetWindow){const t=b();if("status"===e){const e=crypto.randomUUID();this.pending.set(e,t),this.handleResponse({kind:"response",id:e,result:{connected:!1,walletVersion:void 0}})}return t.promise}const n=crypto.randomUUID(),i={kind:"request",id:n,method:e,params:t,sessionId:this.sessionId},r=b();return this.pending.set(n,r),this.post(i),r.promise}onEvent(e){return this.eventHandlers.add(e),()=>{this.eventHandlers.delete(e)}}attachListener(){this.listening||(window.addEventListener("message",this.onWindowMessage),this.listening=!0)}detachListener(){this.listening&&(window.removeEventListener("message",this.onWindowMessage),this.listening=!1)}post(e){try{if(!this.targetWindow)return;this.targetWindow.postMessage(e,this.targetOrigin)}catch(e){}}onWindowMessage(e){if(e.origin!==this.targetOrigin||e.source!==this.targetWindow)return;const t=e.data;if(t&&"object"==typeof t){if("event"===t.kind){for(const e of this.eventHandlers)e(t);return}if("handshake-ack"===t.kind&&t.ok)return void this.handleHandshakeAck();"response"===t.kind&&this.handleResponse(t)}}handleHandshakeAck(){this.walletReady=!0,this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.resolve(),this.initDeferred=void 0)}handleResponse(e){const t=this.pending.get(e.id);if(t)if(this.pending.delete(e.id),e.error){const s=Object.assign(new Error(e.error.message),{code:e.error.code,data:e.error.data});t.reject(s)}else t.resolve(e.result)}startHandshakeLoop(){this.handshakeDeadline=Date.now()+15e3;const e=()=>{if(!this.walletReady)return this.targetWindow?this.handshakeDeadline&&Date.now()>this.handshakeDeadline?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Handshake timed out"))):void this.post({kind:"handshake",sdkVersion:"0.0.0",sessionId:this.sessionId,dapp:{name:this.appName,url:this.appUrl}}):(this.clearHandshakeLoop(),void this.rejectInit(new Error("Target window unavailable before handshake")));this.clearHandshakeLoop()};e(),this.handshakeTimer=window.setInterval(e,300)}clearHandshakeLoop(){null!=this.handshakeTimer&&(clearInterval(this.handshakeTimer),this.handshakeTimer=void 0),this.handshakeDeadline=void 0}rejectInit(e){this.initDeferred&&(this.initDeferred.reject(e),this.initDeferred=void 0)}}var _=Object.defineProperty,C=(e,t,s)=>((e,t,s)=>t in e?_(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function N(t){try{const s=new URL(t).hostname;return s===e||s.endsWith(`.${e}`)}catch{return!1}}const O={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},R="c8#provider_discovery";exports.C8WalletProvider=class{constructor(e){var s,r,a;C(this,"transport"),C(this,"listeners",{});const o=null!=(s=e.dappName)?s:document.title||"Unknown dApp",h=null!=(r=e.dappUrl)?r:location.origin,d=null!=(a=e.network)?a:"mainnet";let c;switch(d){case"devnet":c=t;break;case"testmainnet":c=i;break;case"mainnet":c=n;break;default:throw new Error("Unsupported network: "+d)}const l=function(){var e;if(window.parent===window)return;const t=null==(e=window.location.ancestorOrigins)?void 0:e[0];if(t&&N(t))return t;if(document.referrer)try{const e=new URL(document.referrer).origin;return N(e)?e:void 0}catch{return}}();this.transport=l?new D(o,h,l,window.parent):new E(o,h,c),this.transport.onEvent(e=>{"event"===e.kind&&this.emit(e.event.type,e.event)})}async connect(){await this.transport.request("connect",void 0,!0)}async disconnect(){try{await this.transport.request("disconnect"),this.transport.destroy()}catch(e){}}status(){return this.transport.request("status")}getInstruments(){return this.transport.request("getInstruments")}getAccounts(e){return this.transport.request("getAccounts",{instrumentId:e})}send(e){return this.transport.request("send",e,!0)}createSwapOffer(e){return this.transport.request("createSwapOffer",e,!0)}signAndExecute(e){return this.transport.request("signAndExecute",e,!0)}signMessage(e,t){return this.transport.request("signMessage",{message:e,partyId:t},!0)}signAndExecutePreparedTransfer(e){return this.transport.request("signAndExecutePreparedTransfer",e,!0)}acknowledge(e){return this.transport.request("acknowledge",e,!0)}checkTxStatusById(e){return this.transport.request("checkTxStatusById",e)}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.listeners[e].delete(t)}emit(e,t){var s;for(const n of null!=(s=this.listeners[e])?s:[])n(t)}},exports.HttpClient=T,exports.LocalStorageHelper=r,exports.announceC8Provider=function(e){const t={info:O,provider:e()};window.dispatchEvent(new CustomEvent(R,{detail:t}))},exports.onC8ProviderDiscovered=function(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(R,t),()=>window.removeEventListener(R,t)};
1
+ "use strict";const e="cantor8.tech",t="https://wallet.dev.digik.cantor8.tech",s="https://wallet-backend.dev.digik.cantor8.tech",n="https://wallet.cantor8.tech",i="https://wallet.main.digik.cantor8.tech";class r{static getItem(e){try{const t=localStorage.getItem(e);return t?JSON.parse(t):null}catch(e){return null}}static setItem(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(e){}}static removeItem(e){try{localStorage.removeItem(e)}catch(e){}}}const a={TestCoin1:"TestCoin1",Amulet:"Canton Coin",CBTC:"CBTC",USDCx:"USDCx",CETH:"CETH"},o=e=>{var t;return"Amulet"===e?"Canton Coin":null!=(t=a[null!=e?e:""])?t:e},d={TestCoin1:"TestCoin1",Amulet:"CC",CBTC:"CBTC",USDCx:"USDCx"},h=e=>{var t;return"Amulet"===e?"CC":null!=(t=d[null!=e?e:""])?t:e};var c=Object.defineProperty,l=(e,t,s)=>((e,t,s)=>t in e?c(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const u=class e{constructor(){l(this,"appName"),l(this,"accounts",[]),l(this,"instruments",[]),l(this,"authToken",null),l(this,"isConnected",!1),l(this,"expireAt",null),l(this,"disconnectTimeoutId",null),this.load()}static getInstance(){return e.instance||(e.instance=new e),e.instance}setAppName(e){this.appName=e}getAppName(){return this.appName}setInstruments(e){this.instruments=e}getInstruments(){return this.instruments}setAccounts(e){this.accounts=e,this.instruments=e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:o(e.instrumentId),symbol:h(e.instrumentId)})))}getAccounts(){return this.accounts}setBearerToken(e,t){this.authToken=e,this.isConnected=!0,this.expireAt=t}getExpireAt(){return this.expireAt}setDisconnectTimeoutId(e){this.disconnectTimeoutId&&clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=e}getDisconnectTimeoutId(){return this.disconnectTimeoutId}getBearerToken(){return this.authToken}clear(){this.accounts=[],this.instruments=[],this.authToken=null,this.isConnected=!1,this.expireAt=null,this.disconnectTimeoutId&&(clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=null),r.removeItem(e.SESSION_KEY)}save(){r.setItem(e.SESSION_KEY,{authToken:this.authToken,accounts:this.accounts.map(({accountName:e,partyId:t,publicKey:s,validator:n})=>({accountName:e,partyId:t,publicKey:s,validator:n})),expireAt:this.expireAt})}setConnected(e){this.isConnected=e}getConnected(){return this.isConnected}hasStoredSession(){return!!r.getItem(e.SESSION_KEY)}load(){const t=r.getItem(e.SESSION_KEY);t&&(this.authToken=t.authToken,this.accounts=(t.accounts||[]).filter(e=>!!e.validator).map(e=>({...e,holdings:[]})),this.expireAt=t.expireAt||null)}};l(u,"instance"),l(u,"SESSION_KEY","c8-session");let p=u;var g=Object.defineProperty,f=(e,t,s)=>((e,t,s)=>t in e?g(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const m=class e{constructor(e=5e3){f(this,"pollingInterval",e),f(this,"events",new Map),f(this,"intervals",new Map),f(this,"handlerRegistry",new Map),this.restore()}static getInstance(t=5e3){return e.instance||(e.instance=new e(t)),e.instance}registerHandler(e,t){this.handlerRegistry.set(e,t),this.events.forEach((s,n)=>{s.event.type===e&&(this.stopPolling(n),s.handler=t,this.startPolling(n))})}add(e,t){const s=btoa(`${e}-${JSON.stringify(t)}`);this.events.has(s)&&this.remove(s);const n=this.handlerRegistry.get(e);if(!n)return;const i={key:s,type:e,params:t,createdAt:Date.now()};this.events.set(s,{event:i,handler:n}),this.persist(),this.startPolling(s)}remove(e){this.stopPolling(e),this.events.delete(e),this.persist()}startPolling(t){const s=this.events.get(t);if(!s)return;const{event:n,handler:i}=s,r=async()=>{try{if(n.createdAt&&Date.now()-n.createdAt>e.POLLING_TIMEOUT)return void this.remove(t);await i(n.params)&&this.remove(t)}catch(e){}};r();const a=window.setInterval(r,this.pollingInterval);this.intervals.set(t,a)}stopPolling(e){const t=this.intervals.get(e);void 0!==t&&(window.clearInterval(t),this.intervals.delete(e))}persist(){const t=Array.from(this.events.values()).map(e=>e.event);r.setItem(e.STORAGE_KEY,t)}restore(){const t=r.getItem(e.STORAGE_KEY);if(t&&Array.isArray(t)){const s=Date.now();t.forEach(t=>{if(t.createdAt&&s-t.createdAt>e.POLLING_TIMEOUT)return;const n=this.handlerRegistry.get(t.key);n?(this.events.set(t.key,{event:t,handler:n}),this.startPolling(t.key)):this.events.set(t.key,{event:t,handler:async()=>!1})})}}clear(){this.events.clear(),this.intervals.forEach(e=>window.clearInterval(e)),this.intervals.clear(),this.persist(),r.removeItem(e.STORAGE_KEY)}getEvents(){return Array.from(this.events.values()).map(e=>e.event)}};f(m,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),f(m,"type"),f(m,"instance"),f(m,"STORAGE_KEY","c8-polling-events"),f(m,"POLLING_TIMEOUT",3e5);let w=m;var v=Object.defineProperty;class y{constructor(e){((e,t,s)=>{((e,t,s)=>{t in e?v(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s})(e,t+"",s)})(this,"baseUrl"),this.baseUrl=e.endsWith("/")?e.slice(0,-1):e}async request(e,t={}){const s=p.getInstance().getBearerToken(),n=p.getInstance().getAppName(),i=new Headers(t.headers);s&&(i.set("Authorization",`Bearer ${s}`),i.set("X-App-Name",null!=n?n:"Unknown App")),i.set("x-feat-decimals","1");const r=await fetch(`${this.baseUrl}${e}`,{...t,headers:i});if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);return await r.json()}async getActiveContracts(e={}){var t,s,n;const i=null!=(t=e.limit)?t:1e4;if(!Number.isInteger(i)||i<1||i>2147483647)throw new Error("limit must be a positive 32-bit integer");if(void 0!==e.activeAtOffset&&("string"!=typeof e.activeAtOffset||!/^\d+$/.test(e.activeAtOffset)||BigInt(e.activeAtOffset)>BigInt("9223372036854775807")))throw new Error("activeAtOffset must be a nonnegative 64-bit integer string");if(void 0!==e.paginated&&"boolean"!=typeof e.paginated)throw new Error("paginated must be a boolean");if(void 0!==e.after&&("string"!=typeof e.after||!e.after))throw new Error("after must be a nonempty string");const r=new URLSearchParams({limit:String(i),include_created_event_blob:String(null!=(s=e.includeCreatedEventBlob)&&s),paginated:String(null==(n=e.paginated)||n)});for(const[t,s]of[["template_id",e.templateIds],["interface_id",e.interfaceIds]]){if(void 0!==s&&(!Array.isArray(s)||s.some(e=>"string"!=typeof e||!e)))throw new Error(`${t} filters must be nonempty strings`);for(const e of null!=s?s:[])r.append(t,e)}if(void 0!==e.includeCreatedEventBlob&&"boolean"!=typeof e.includeCreatedEventBlob)throw new Error("includeCreatedEventBlob must be a boolean");void 0!==e.activeAtOffset&&r.set("active_at_offset",e.activeAtOffset),void 0!==e.after&&r.set("after",e.after);const a=await this.scannerRequest("/contracts/active",e.partyId,"acting_party",r);if(!Array.isArray(a))throw new Error("Expected an active contracts array");return a}async scannerRequest(e,t,s,n){const i=p.getInstance(),r=i.getBearerToken(),a=i.getAccounts()[0],o=i.getExpireAt();if(!r||!a||null!=o&&o<=Date.now())throw new Error("Connect to the wallet before reading Scanner data");if(void 0!==t&&t!==a.partyId)throw new Error("Scanner reads are available only for the connected primary account");const d=a.validator.scannerApiUrl;if(!d)throw new Error("Scanner endpoint unavailable; disconnect and reconnect to the wallet");n.set(s,a.partyId);const h=await fetch(`${d.replace(/\/$/,"")}${e}?${n}`,{headers:{Authorization:`Bearer ${r}`}});if(!h.ok)throw new Error(`HTTP error! status: ${h.status}`);return h.json()}async getLedgerUpdates(e={}){var t,s;const n=null!=(t=e.limit)?t:500;if(!Number.isInteger(n)||n<1||n>1e3)throw new Error("limit must be an integer between 1 and 1000");const i=new URLSearchParams({limit:String(n)});if(void 0!==e.templateIds&&(!Array.isArray(e.templateIds)||e.templateIds.some(e=>"string"!=typeof e||!e)))throw new Error("template_id filters must be nonempty strings");for(const t of null!=(s=e.templateIds)?s:[])i.append("template_id",t);if(void 0!==e.cursor){const t="string"==typeof e.cursor&&/^(\d+):(-?\d+)$/.exec(e.cursor);if(!t||BigInt(t[1])>BigInt("9223372036854775807")||BigInt(t[2])<BigInt("-2147483648")||BigInt(t[2])>BigInt("2147483647"))throw new Error("cursor must be a nonnegative 64-bit offset and signed 32-bit node ID separated by a colon");i.set("after_offset",t[1]),i.set("after_node_id",t[2])}if(void 0!==e.eventType){if("created"!==e.eventType&&"exercised"!==e.eventType)throw new Error("eventType must be created or exercised");i.set("event_type",e.eventType)}if(void 0!==e.consuming){if("boolean"!=typeof e.consuming)throw new Error("consuming must be a boolean");i.set("consuming",String(e.consuming))}const r=await this.scannerRequest("/ledger-nodes",e.partyId,"party",i);if(!r||!Array.isArray(r.nodes)||"boolean"!=typeof r.complete)throw new Error("Expected a ledger updates page");return r}async getBalance(){return this.request("/api/balance")}async getTransferStatus(e){return this.request(`/api/transfer/status?command_id=${e}`)}async getContractsSetupState(){return this.request("/api/register/status_v2")}}var I=Object.defineProperty,T=(e,t,s)=>((e,t,s)=>t in e?I(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function E(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class k{constructor(e,r,a=t){let o;switch(T(this,"appName",e),T(this,"appUrl",r),T(this,"origin",a),T(this,"WINDOW_NAME","c8-wallet"),T(this,"WINDOW_WIDTH",475),T(this,"WINDOW_HEIGHT",762),T(this,"popup"),T(this,"sessionId",crypto.randomUUID()),T(this,"listening",!1),T(this,"walletReady",!1),T(this,"pending",new Map),T(this,"eventHandlers",new Set),T(this,"handshakeTimer"),T(this,"handshakeDeadline"),T(this,"closeWatcherTimer"),T(this,"pollingManager",w.getInstance()),T(this,"session",p.getInstance()),T(this,"initDeferred"),T(this,"httpClient"),this.onWindowMessage=this.onWindowMessage.bind(this),this.handleRestoreSession=this.handleRestoreSession.bind(this),this.handleTrackTxStatus=this.handleTrackTxStatus.bind(this),this.handleAccountUpdate=this.handleAccountUpdate.bind(this),this.session.setAppName(this.appName),this.attachListener(),this.origin){case t:o=s;break;case n:case i:o="https://wallet-backend.main.digik.cantor8.tech";break;default:o=s}this.httpClient=new y(o),this.pollingManager.registerHandler(w.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(w.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(w.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){this.session.hasStoredSession()&&this.pollingManager.add(w.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=this.session.getAccounts().find(t=>t.partyId===e.party_id);if(!t)return!1;const s=[{accountName:t.accountName,partyId:e.party_id,publicKey:t.publicKey,validator:t.validator,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(s),this.session.save()}return!0}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}async getTransferStatusById(e){try{const t=await this.httpClient.getTransferStatus(e);let s;switch(t.status){case"success":s="confirmed";break;case"failed":s="failed";break;default:s="pending"}return t.status=s,t}catch(e){return e instanceof Error&&e.message.includes("401")&&this.destroy(),null}}async handleTrackTxStatus(e){try{const t=await this.httpClient.getTransferStatus(e.txId);if(e.status!==t.status){let s;switch(t.status){case"success":s="confirmed";break;case"failed":s="failed";break;default:s="pending"}return this.emitSyntheticEvent({type:"txChanged",txId:e.txId,status:s}),e.status=t.status,this.pollingManager.persist(),"pending"!==t.status&&this.pollingManager.add(w.EVENT_TYPES.UPDATE_ACCOUNT,{txId:e.txId}),"success"===t.status||"failed"===t.status}}catch(t){if(t instanceof Error&&(t.message.includes("401")&&this.destroy(),t.message.includes("404")))return this.emitSyntheticEvent({type:"txChanged",txId:e.txId,status:"failed"}),!0}return!1}async handleRestoreSession(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=this.session.getAccounts().find(t=>t.partyId===e.party_id);if(!t)return!1;const s=[{accountName:t.accountName,partyId:e.party_id,publicKey:t.publicKey,validator:t.validator,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(s),this.session.save(),this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const n=this.session.getExpireAt();return n&&this.scheduleDisconnect(n),!0}}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}get WALLET_EMBEDDED(){return`${this.origin}/embedded/`}async init(e){var t;if(void 0!==this.popup&&(null==(t=this.popup)||!t.closed))return;if(this.initDeferred||(this.initDeferred=E()),this.listening||this.attachListener(),this.popup&&!this.popup.closed)return this.popup.focus(),null==this.handshakeTimer&&this.startHandshakeLoop(),this.initDeferred.promise;const s=new URL(null!=e?e:"",this.WALLET_EMBEDDED);if(this.popup=window.open(s,this.WINDOW_NAME,`width=${this.WINDOW_WIDTH},height=${this.WINDOW_HEIGHT}`),!this.popup){const e=new Error("Failed to open popup window");Object.assign(e,{code:"POPUP_BLOCKED",message:"browser blocked the popup window"}),this.rejectInit(e)}return this.startHandshakeLoop(),this.initDeferred.promise}emitSyntheticEvent(e){for(const t of this.eventHandlers)try{t({kind:"event",event:e})}catch(e){}}scheduleDisconnect(e){if(!e)return;const t=e-Date.now();if(t>0){const e=setTimeout(()=>{this.destroy("authToken expired")},t);this.session.setDisconnectTimeoutId(e)}else this.destroy("authToken expired")}destroy(e="destroyed"){try{this.emitSyntheticEvent({type:"disconnected",reason:e}),this.detachListener(),this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.reject(new Error("Transport destroyed")),this.initDeferred=void 0);for(const[,e]of this.pending)e.reject(new Error("Transport destroyed"));this.pending.clear(),this.popup&&!this.popup.closed&&this.popup.close(),this.popup=void 0,this.walletReady=!1,this.session.clear(),this.pollingManager.clear()}catch(e){}}async request(e,t,s){var n,i,r,a,o,d,h,c,l,u,p,g,f,m,w,v;const y=crypto.randomUUID(),I=E();this.pending.set(y,I);try{if("connect"===e){if(this.session.getBearerToken())return this.handleResponse({kind:"response",id:y,result:null}),I.promise;this.session.getBearerToken()||(this.walletReady=!1),await this.init()}if("send"===e&&(this.walletReady=!1,await this.init("confirmTransaction")),"createSwapOffer"===e&&(this.walletReady=!1,await this.init("confirmSwapOffer")),"signMessage"===e&&(this.walletReady=!1,await this.init("confirmSignMessage")),"signAndExecute"===e&&(this.walletReady=!1,await this.init("signAndExecute")),"status"===e)return this.handleResponse({kind:"response",id:y,result:{connected:this.session.getConnected(),walletVersion:void 0}}),I.promise;if(s&&(null==(n=this.popup)||n.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:y,result:{instruments:e}}),I.promise}if("getActiveContracts"===e){const e=await this.httpClient.getActiveContracts(t);return this.handleResponse({kind:"response",id:y,result:e}),I.promise}if("getLedgerUpdates"===e){const e=await this.httpClient.getLedgerUpdates(t);return this.handleResponse({kind:"response",id:y,result:e}),I.promise}if("getContractsSetupState"===e){const e=await this.httpClient.getContractsSetupState(),t={isRegistered:e.is_registered,isConfirmed:e.is_confirmed,isPreapprovalSet:e.is_preapproval_set,isPreapprovalInProgress:e.is_preapproval_in_progress,isAutoAcceptSet:e.is_auto_accept_set,isAutoAcceptInProgress:e.is_auto_accept_in_progress,isUsdcBridgeSet:e.is_usdc_bridge_set,isUsdcBridgeSetupInProgress:e.is_usdc_bridge_setup_in_progress,isWithdrawalDelegationSet:e.is_withdrawal_delegation_set,isWithdrawalDelegationInProgress:e.is_withdrawal_delegation_in_progress,isMergeDelegationSet:e.is_merge_delegation_set,isMergeDelegationInProgress:e.is_merge_delegation_in_progress};return this.handleResponse({kind:"response",id:y,result:t}),I.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:y,result:{accounts:e}}),I.promise}if("checkTxStatusById"===e){const e=t,s=await this.getTransferStatusById(null==e?void 0:e.txId);if(s){const e={status:s.status,transfer:{senderPartyId:null!=(r=null==(i=s.transfer)?void 0:i.party_id)?r:"",receiverPartyId:null!=(o=null==(a=s.transfer)?void 0:a.party_id2)?o:"",amount:Number(null!=(h=null==(d=s.transfer)?void 0:d.amount)?h:"0"),networkFees:Number(null!=(l=null==(c=s.transfer)?void 0:c.network_fees)?l:"0"),instrumentId:null!=(p=null==(u=s.transfer)?void 0:u.instrument_id)?p:"",txId:null!=(f=null==(g=s.transfer)?void 0:g.command_id)?f:"",created_at:null!=(w=null==(m=s.transfer)?void 0:m.created_at)?w:"",memo:null==(v=s.transfer)?void 0:v.reason}};this.handleResponse({kind:"response",id:y,result:e})}else this.handleResponse({kind:"response",id:y,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return I.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:y,result:null}),I.promise;const T={kind:"request",id:y,method:e,params:t,sessionId:this.sessionId};this.post(T)}catch(e){this.pending.delete(y),I.reject(e)}return I.promise}onEvent(e){return this.eventHandlers.add(e),()=>{this.eventHandlers.delete(e)}}attachListener(){this.listening||(window.addEventListener("message",this.onWindowMessage),this.listening=!0)}detachListener(){this.listening&&(window.removeEventListener("message",this.onWindowMessage),this.listening=!1)}post(e){try{if(!this.popup||this.popup.closed)return;this.popup.postMessage(e,this.origin)}catch(e){}}onWindowMessage(e){if(e.origin!==this.origin)return;const t=e.data;if(t&&"object"==typeof t){if("event"===t.kind){for(const e of this.eventHandlers)"txInitiated"===t.event.type&&this.pollingManager.add(w.EVENT_TYPES.TRACK_TX_STATUS,{txId:t.event.txId,status:"initiated"}),e(t);return}if("internal_event"===t.kind)return void this.pollingManager.add(t.event.type,{wop:"wopwop"});if("auth-flow"===t.kind&&(this.session.setBearerToken(t.token,t.expireAt),this.session.setAccounts(t.accounts),this.session.setInstruments(t.instruments),this.session.save(),this.scheduleDisconnect(t.expireAt)),"handshake-ack"===t.kind&&t.ok)return void this.handleHandshakeAck();"response"===t.kind&&this.handleResponse(t)}}handleHandshakeAck(){this.walletReady=!0,this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.resolve(),this.initDeferred=void 0)}handleResponse(e){const t=this.pending.get(e.id);if(t)if(this.pending.delete(e.id),e.error){const s=new Error(e.error.message||"Unknown Error");Object.assign(s,{code:e.error.code,data:e.error.data}),t.reject(s)}else t.resolve(e.result)}startHandshakeLoop(){this.handshakeDeadline=Date.now()+55e3;const e=()=>{if(!this.walletReady)return!this.popup||this.popup.closed?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Popup closed before handshake"))):this.handshakeDeadline&&Date.now()>this.handshakeDeadline?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Handshake timed out"))):void this.post({kind:"handshake",sdkVersion:"0.0.0",sessionId:this.sessionId,dapp:{name:this.appName,url:this.appUrl}});this.clearHandshakeLoop()};e(),this.handshakeTimer=window.setInterval(e,300)}clearHandshakeLoop(){null!=this.handshakeTimer&&(clearInterval(this.handshakeTimer),this.handshakeTimer=void 0),this.handshakeDeadline=void 0}rejectInit(e){this.initDeferred&&(Object.assign(e,{code:"INITIALIZATION_FAILED",message:e.message}),this.initDeferred.reject(e),this.initDeferred=void 0)}startPopupClosedWatcher(){const e=this.popup;if(!e)return;const t=window.setInterval(()=>{(!e||e.closed)&&(clearInterval(t),this.destroy())},300);this.closeWatcherTimer=t}}var S=Object.defineProperty,b=(e,t,s)=>((e,t,s)=>t in e?S(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function A(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class _{constructor(e,t,s,n){b(this,"appName",e),b(this,"appUrl",t),b(this,"targetOrigin",s),b(this,"targetWindow",n),b(this,"sessionId",crypto.randomUUID()),b(this,"listening",!1),b(this,"walletReady",!1),b(this,"pending",new Map),b(this,"eventHandlers",new Set),b(this,"handshakeTimer"),b(this,"handshakeDeadline"),b(this,"initDeferred"),this.onWindowMessage=this.onWindowMessage.bind(this),this.attachListener()}async init(){if(!this.walletReady){if(this.initDeferred||(this.initDeferred=A()),this.listening||this.attachListener(),!this.targetWindow){const e=new Error("ThinTransport targetWindow is not available");throw this.rejectInit(e),e}return!this.walletReady&&null==this.handshakeTimer&&this.startHandshakeLoop(),this.initDeferred.promise}}destroy(){try{for(const e of this.eventHandlers)try{e({kind:"event",event:{type:"disconnected",reason:"destroyed"}})}catch{}this.detachListener(),this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.reject(new Error("Transport destroyed")),this.initDeferred=void 0);for(const[,e]of this.pending)e.reject(new Error("Transport destroyed"));this.pending.clear(),this.walletReady=!1}catch(e){}}async request(e,t,s){if("connect"===e&&await this.init(),!this.targetWindow){const t=A();if("status"===e){const e=crypto.randomUUID();this.pending.set(e,t),this.handleResponse({kind:"response",id:e,result:{connected:!1,walletVersion:void 0}})}return t.promise}const n=crypto.randomUUID(),i={kind:"request",id:n,method:e,params:t,sessionId:this.sessionId},r=A();return this.pending.set(n,r),this.post(i),r.promise}onEvent(e){return this.eventHandlers.add(e),()=>{this.eventHandlers.delete(e)}}attachListener(){this.listening||(window.addEventListener("message",this.onWindowMessage),this.listening=!0)}detachListener(){this.listening&&(window.removeEventListener("message",this.onWindowMessage),this.listening=!1)}post(e){try{if(!this.targetWindow)return;this.targetWindow.postMessage(e,this.targetOrigin)}catch(e){}}onWindowMessage(e){if(e.origin!==this.targetOrigin||e.source!==this.targetWindow)return;const t=e.data;if(t&&"object"==typeof t){if("event"===t.kind){for(const e of this.eventHandlers)e(t);return}if("handshake-ack"===t.kind&&t.ok)return void this.handleHandshakeAck();"response"===t.kind&&this.handleResponse(t)}}handleHandshakeAck(){this.walletReady=!0,this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.resolve(),this.initDeferred=void 0)}handleResponse(e){const t=this.pending.get(e.id);if(t)if(this.pending.delete(e.id),e.error){const s=Object.assign(new Error(e.error.message),{code:e.error.code,data:e.error.data});t.reject(s)}else t.resolve(e.result)}startHandshakeLoop(){this.handshakeDeadline=Date.now()+15e3;const e=()=>{if(!this.walletReady)return this.targetWindow?this.handshakeDeadline&&Date.now()>this.handshakeDeadline?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Handshake timed out"))):void this.post({kind:"handshake",sdkVersion:"0.0.0",sessionId:this.sessionId,dapp:{name:this.appName,url:this.appUrl}}):(this.clearHandshakeLoop(),void this.rejectInit(new Error("Target window unavailable before handshake")));this.clearHandshakeLoop()};e(),this.handshakeTimer=window.setInterval(e,300)}clearHandshakeLoop(){null!=this.handshakeTimer&&(clearInterval(this.handshakeTimer),this.handshakeTimer=void 0),this.handshakeDeadline=void 0}rejectInit(e){this.initDeferred&&(this.initDeferred.reject(e),this.initDeferred=void 0)}}var D=Object.defineProperty,C=(e,t,s)=>((e,t,s)=>t in e?D(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function O(t){try{const s=new URL(t).hostname;return s===e||s.endsWith(`.${e}`)}catch{return!1}}const R={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},N="c8#provider_discovery";exports.C8WalletProvider=class{constructor(e){var s,r,a;C(this,"transport"),C(this,"listeners",{});const o=null!=(s=e.dappName)?s:document.title||"Unknown dApp",d=null!=(r=e.dappUrl)?r:location.origin,h=null!=(a=e.network)?a:"mainnet";let c;switch(h){case"devnet":c=t;break;case"testmainnet":c=i;break;case"mainnet":c=n;break;default:throw new Error("Unsupported network: "+h)}const l=function(){var e;if(window.parent===window)return;const t=null==(e=window.location.ancestorOrigins)?void 0:e[0];if(t&&O(t))return t;if(document.referrer)try{const e=new URL(document.referrer).origin;return O(e)?e:void 0}catch{return}}();this.transport=l?new _(o,d,l,window.parent):new k(o,d,c),this.transport.onEvent(e=>{"event"===e.kind&&this.emit(e.event.type,e.event)})}async connect(){await this.transport.request("connect",void 0,!0)}async disconnect(){try{await this.transport.request("disconnect"),this.transport.destroy()}catch(e){}}status(){return this.transport.request("status")}getContractsSetupState(){return this.transport.request("getContractsSetupState")}getInstruments(){return this.transport.request("getInstruments")}getActiveContracts(e={}){return this.transport.request("getActiveContracts",e)}getLedgerUpdates(e={}){return this.transport.request("getLedgerUpdates",e)}getAccounts(e){return this.transport.request("getAccounts",{instrumentId:e})}send(e){return this.transport.request("send",e,!0)}createSwapOffer(e){return this.transport.request("createSwapOffer",e,!0)}signAndExecute(e){return this.transport.request("signAndExecute",e,!0)}signMessage(e,t){return this.transport.request("signMessage",{message:e,partyId:t},!0)}signAndExecutePreparedTransfer(e){return this.transport.request("signAndExecutePreparedTransfer",e,!0)}acknowledge(e){return this.transport.request("acknowledge",e,!0)}checkTxStatusById(e){return this.transport.request("checkTxStatusById",e)}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.listeners[e].delete(t)}emit(e,t){var s;for(const n of null!=(s=this.listeners[e])?s:[])n(t)}},exports.HttpClient=y,exports.LocalStorageHelper=r,exports.announceC8Provider=function(e){const t={info:R,provider:e()};window.dispatchEvent(new CustomEvent(N,{detail:t}))},exports.onC8ProviderDiscovered=function(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(N,t),()=>window.removeEventListener(N,t)};
package/dist/index.esm.js CHANGED
@@ -1 +1 @@
1
- const e="cantor8.tech",t="https://wallet.dev.digik.cantor8.tech",s="https://wallet-backend.dev.digik.cantor8.tech",n="https://wallet.cantor8.tech",i="https://wallet.main.digik.cantor8.tech";class r{static getItem(e){try{const t=localStorage.getItem(e);return t?JSON.parse(t):null}catch(e){return null}}static setItem(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(e){}}static removeItem(e){try{localStorage.removeItem(e)}catch(e){}}}const a={TestCoin1:"TestCoin1",Amulet:"Canton Coin",CBTC:"CBTC",USDCx:"USDCx",CETH:"CETH"},o=e=>{var t;return"Amulet"===e?"Canton Coin":null!=(t=a[null!=e?e:""])?t:e},h={TestCoin1:"TestCoin1",Amulet:"CC",CBTC:"CBTC",USDCx:"USDCx"},d=e=>{var t;return"Amulet"===e?"CC":null!=(t=h[null!=e?e:""])?t:e};var c=Object.defineProperty,l=(e,t,s)=>((e,t,s)=>t in e?c(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const u=class e{constructor(){l(this,"appName"),l(this,"accounts",[]),l(this,"instruments",[]),l(this,"authToken",null),l(this,"isConnected",!1),l(this,"expireAt",null),l(this,"disconnectTimeoutId",null),this.load()}static getInstance(){return e.instance||(e.instance=new e),e.instance}setAppName(e){this.appName=e}getAppName(){return this.appName}setInstruments(e){this.instruments=e}getInstruments(){return this.instruments}setAccounts(e){this.accounts=e,this.instruments=e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:o(e.instrumentId),symbol:d(e.instrumentId)})))}getAccounts(){return this.accounts}setBearerToken(e,t){this.authToken=e,this.isConnected=!0,this.expireAt=t}getExpireAt(){return this.expireAt}setDisconnectTimeoutId(e){this.disconnectTimeoutId&&clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=e}getDisconnectTimeoutId(){return this.disconnectTimeoutId}getBearerToken(){return this.authToken}clear(){this.accounts=[],this.instruments=[],this.authToken=null,this.isConnected=!1,this.expireAt=null,this.disconnectTimeoutId&&(clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=null),r.removeItem(e.SESSION_KEY)}save(){r.setItem(e.SESSION_KEY,{authToken:this.authToken,accounts:this.accounts.map(({accountName:e,partyId:t,publicKey:s,validator:n})=>({accountName:e,partyId:t,publicKey:s,validator:n})),expireAt:this.expireAt})}setConnected(e){this.isConnected=e}getConnected(){return this.isConnected}hasStoredSession(){return!!r.getItem(e.SESSION_KEY)}load(){const t=r.getItem(e.SESSION_KEY);t&&(this.authToken=t.authToken,this.accounts=(t.accounts||[]).filter(e=>!!e.validator).map(e=>({...e,holdings:[]})),this.expireAt=t.expireAt||null)}};l(u,"instance"),l(u,"SESSION_KEY","c8-session");let p=u;var g=Object.defineProperty,m=(e,t,s)=>((e,t,s)=>t in e?g(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const f=class e{constructor(e=5e3){this.pollingInterval=e,m(this,"events",new Map),m(this,"intervals",new Map),m(this,"handlerRegistry",new Map),this.restore()}static getInstance(t=5e3){return e.instance||(e.instance=new e(t)),e.instance}registerHandler(e,t){this.handlerRegistry.set(e,t),this.events.forEach((s,n)=>{s.event.type===e&&(this.stopPolling(n),s.handler=t,this.startPolling(n))})}add(e,t){const s=btoa(`${e}-${JSON.stringify(t)}`);this.events.has(s)&&this.remove(s);const n=this.handlerRegistry.get(e);if(!n)return;const i={key:s,type:e,params:t,createdAt:Date.now()};this.events.set(s,{event:i,handler:n}),this.persist(),this.startPolling(s)}remove(e){this.stopPolling(e),this.events.delete(e),this.persist()}startPolling(t){const s=this.events.get(t);if(!s)return;const{event:n,handler:i}=s,r=async()=>{try{if(n.createdAt&&Date.now()-n.createdAt>e.POLLING_TIMEOUT)return void this.remove(t);await i(n.params)&&this.remove(t)}catch(e){}};r();const a=window.setInterval(r,this.pollingInterval);this.intervals.set(t,a)}stopPolling(e){const t=this.intervals.get(e);void 0!==t&&(window.clearInterval(t),this.intervals.delete(e))}persist(){const t=Array.from(this.events.values()).map(e=>e.event);r.setItem(e.STORAGE_KEY,t)}restore(){const t=r.getItem(e.STORAGE_KEY);if(t&&Array.isArray(t)){const s=Date.now();t.forEach(t=>{if(t.createdAt&&s-t.createdAt>e.POLLING_TIMEOUT)return;const n=this.handlerRegistry.get(t.key);n?(this.events.set(t.key,{event:t,handler:n}),this.startPolling(t.key)):this.events.set(t.key,{event:t,handler:async()=>!1})})}}clear(){this.events.clear(),this.intervals.forEach(e=>window.clearInterval(e)),this.intervals.clear(),this.persist(),r.removeItem(e.STORAGE_KEY)}getEvents(){return Array.from(this.events.values()).map(e=>e.event)}};m(f,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),m(f,"type"),m(f,"instance"),m(f,"STORAGE_KEY","c8-polling-events"),m(f,"POLLING_TIMEOUT",3e5);let v=f;var w=Object.defineProperty;class T{constructor(e){((e,t,s)=>{((e,t,s)=>{t in e?w(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s})(e,t+"",s)})(this,"baseUrl"),this.baseUrl=e.endsWith("/")?e.slice(0,-1):e}async request(e,t={}){const s=p.getInstance().getBearerToken(),n=p.getInstance().getAppName(),i=new Headers(t.headers);s&&(i.set("Authorization",`Bearer ${s}`),i.set("X-App-Name",null!=n?n:"Unknown App")),i.set("x-feat-decimals","1");const r=await fetch(`${this.baseUrl}${e}`,{...t,headers:i});if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);return await r.json()}async getBalance(){return this.request("/api/balance")}async getTransferStatus(e){return this.request(`/api/transfer/status?command_id=${e}`)}}var y=Object.defineProperty,k=(e,t,s)=>((e,t,s)=>t in e?y(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function I(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class E{constructor(e,r,a=t){let o;switch(this.appName=e,this.appUrl=r,this.origin=a,k(this,"WINDOW_NAME","c8-wallet"),k(this,"WINDOW_WIDTH",475),k(this,"WINDOW_HEIGHT",762),k(this,"popup"),k(this,"sessionId",crypto.randomUUID()),k(this,"listening",!1),k(this,"walletReady",!1),k(this,"pending",new Map),k(this,"eventHandlers",new Set),k(this,"handshakeTimer"),k(this,"handshakeDeadline"),k(this,"closeWatcherTimer"),k(this,"pollingManager",v.getInstance()),k(this,"session",p.getInstance()),k(this,"initDeferred"),k(this,"httpClient"),this.onWindowMessage=this.onWindowMessage.bind(this),this.handleRestoreSession=this.handleRestoreSession.bind(this),this.handleTrackTxStatus=this.handleTrackTxStatus.bind(this),this.handleAccountUpdate=this.handleAccountUpdate.bind(this),this.session.setAppName(this.appName),this.attachListener(),this.origin){case t:o=s;break;case n:case i:o="https://wallet-backend.main.cantor8.tech";break;default:o=s}this.httpClient=new T(o),this.pollingManager.registerHandler(v.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(v.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(v.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){this.session.hasStoredSession()&&this.pollingManager.add(v.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=this.session.getAccounts().find(t=>t.partyId===e.party_id);if(!t)return!1;const s=[{accountName:t.accountName,partyId:e.party_id,publicKey:t.publicKey,validator:t.validator,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(s),this.session.save()}return!0}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}async getTransferStatusById(e){try{const t=await this.httpClient.getTransferStatus(e);let s;switch(t.status){case"success":s="confirmed";break;case"failed":s="failed";break;default:s="pending"}return t.status=s,t}catch(e){return e instanceof Error&&e.message.includes("401")&&this.destroy(),null}}async handleTrackTxStatus(e){try{const t=await this.httpClient.getTransferStatus(e.txId);if(e.status!==t.status){let s;switch(t.status){case"success":s="confirmed";break;case"failed":s="failed";break;default:s="pending"}return this.emitSyntheticEvent({type:"txChanged",txId:e.txId,status:s}),e.status=t.status,this.pollingManager.persist(),"pending"!==t.status&&this.pollingManager.add(v.EVENT_TYPES.UPDATE_ACCOUNT,{txId:e.txId}),"success"===t.status||"failed"===t.status}}catch(t){if(t instanceof Error&&(t.message.includes("401")&&this.destroy(),t.message.includes("404")))return this.emitSyntheticEvent({type:"txChanged",txId:e.txId,status:"failed"}),!0}return!1}async handleRestoreSession(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=this.session.getAccounts().find(t=>t.partyId===e.party_id);if(!t)return!1;const s=[{accountName:t.accountName,partyId:e.party_id,publicKey:t.publicKey,validator:t.validator,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(s),this.session.save(),this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const n=this.session.getExpireAt();return n&&this.scheduleDisconnect(n),!0}}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}get WALLET_EMBEDDED(){return`${this.origin}/embedded/`}async init(e){var t;if(void 0!==this.popup&&(null==(t=this.popup)||!t.closed))return;if(this.initDeferred||(this.initDeferred=I()),this.listening||this.attachListener(),this.popup&&!this.popup.closed)return this.popup.focus(),null==this.handshakeTimer&&this.startHandshakeLoop(),this.initDeferred.promise;const s=new URL(null!=e?e:"",this.WALLET_EMBEDDED);if(this.popup=window.open(s,this.WINDOW_NAME,`width=${this.WINDOW_WIDTH},height=${this.WINDOW_HEIGHT}`),!this.popup){const e=new Error("Failed to open popup window");Object.assign(e,{code:"POPUP_BLOCKED",message:"browser blocked the popup window"}),this.rejectInit(e)}return this.startHandshakeLoop(),this.initDeferred.promise}emitSyntheticEvent(e){for(const t of this.eventHandlers)try{t({kind:"event",event:e})}catch(e){}}scheduleDisconnect(e){if(!e)return;const t=e-Date.now();if(t>0){const e=setTimeout(()=>{this.destroy("authToken expired")},t);this.session.setDisconnectTimeoutId(e)}else this.destroy("authToken expired")}destroy(e="destroyed"){try{this.emitSyntheticEvent({type:"disconnected",reason:e}),this.detachListener(),this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.reject(new Error("Transport destroyed")),this.initDeferred=void 0);for(const[,e]of this.pending)e.reject(new Error("Transport destroyed"));this.pending.clear(),this.popup&&!this.popup.closed&&this.popup.close(),this.popup=void 0,this.walletReady=!1,this.session.clear(),this.pollingManager.clear()}catch(e){}}async request(e,t,s){var n,i,r,a,o,h,d,c,l,u,p,g,m,f,v,w;const T=crypto.randomUUID(),y=I();this.pending.set(T,y);try{if("connect"===e){if(this.session.getBearerToken())return this.handleResponse({kind:"response",id:T,result:null}),y.promise;this.session.getBearerToken()||(this.walletReady=!1),await this.init()}if("send"===e&&(this.walletReady=!1,await this.init("confirmTransaction")),"createSwapOffer"===e&&(this.walletReady=!1,await this.init("confirmSwapOffer")),"signMessage"===e&&(this.walletReady=!1,await this.init("confirmSignMessage")),"signAndExecute"===e&&(this.walletReady=!1,await this.init("signAndExecute")),"status"===e)return this.handleResponse({kind:"response",id:T,result:{connected:this.session.getConnected(),walletVersion:void 0}}),y.promise;if(s&&(null==(n=this.popup)||n.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:T,result:{instruments:e}}),y.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:T,result:{accounts:e}}),y.promise}if("checkTxStatusById"===e){const e=t,s=await this.getTransferStatusById(null==e?void 0:e.txId);if(s){const e={status:s.status,transfer:{senderPartyId:null!=(r=null==(i=s.transfer)?void 0:i.party_id)?r:"",receiverPartyId:null!=(o=null==(a=s.transfer)?void 0:a.party_id2)?o:"",amount:Number(null!=(d=null==(h=s.transfer)?void 0:h.amount)?d:"0"),networkFees:Number(null!=(l=null==(c=s.transfer)?void 0:c.network_fees)?l:"0"),instrumentId:null!=(p=null==(u=s.transfer)?void 0:u.instrument_id)?p:"",txId:null!=(m=null==(g=s.transfer)?void 0:g.command_id)?m:"",created_at:null!=(v=null==(f=s.transfer)?void 0:f.created_at)?v:"",memo:null==(w=s.transfer)?void 0:w.reason}};this.handleResponse({kind:"response",id:T,result:e})}else this.handleResponse({kind:"response",id:T,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return y.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:T,result:null}),y.promise;const k={kind:"request",id:T,method:e,params:t,sessionId:this.sessionId};this.post(k)}catch(e){this.pending.delete(T),y.reject(e)}return y.promise}onEvent(e){return this.eventHandlers.add(e),()=>{this.eventHandlers.delete(e)}}attachListener(){this.listening||(window.addEventListener("message",this.onWindowMessage),this.listening=!0)}detachListener(){this.listening&&(window.removeEventListener("message",this.onWindowMessage),this.listening=!1)}post(e){try{if(!this.popup||this.popup.closed)return;this.popup.postMessage(e,this.origin)}catch(e){}}onWindowMessage(e){if(e.origin!==this.origin)return;const t=e.data;if(t&&"object"==typeof t){if("event"===t.kind){for(const e of this.eventHandlers)"txInitiated"===t.event.type&&this.pollingManager.add(v.EVENT_TYPES.TRACK_TX_STATUS,{txId:t.event.txId,status:"initiated"}),e(t);return}if("internal_event"===t.kind)return void this.pollingManager.add(t.event.type,{wop:"wopwop"});if("auth-flow"===t.kind&&(this.session.setBearerToken(t.token,t.expireAt),this.session.setAccounts(t.accounts),this.session.setInstruments(t.instruments),this.session.save(),this.scheduleDisconnect(t.expireAt)),"handshake-ack"===t.kind&&t.ok)return void this.handleHandshakeAck();"response"===t.kind&&this.handleResponse(t)}}handleHandshakeAck(){this.walletReady=!0,this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.resolve(),this.initDeferred=void 0)}handleResponse(e){const t=this.pending.get(e.id);if(t)if(this.pending.delete(e.id),e.error){const s=new Error(e.error.message||"Unknown Error");Object.assign(s,{code:e.error.code,data:e.error.data}),t.reject(s)}else t.resolve(e.result)}startHandshakeLoop(){this.handshakeDeadline=Date.now()+55e3;const e=()=>{if(!this.walletReady)return!this.popup||this.popup.closed?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Popup closed before handshake"))):this.handshakeDeadline&&Date.now()>this.handshakeDeadline?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Handshake timed out"))):void this.post({kind:"handshake",sdkVersion:"0.0.0",sessionId:this.sessionId,dapp:{name:this.appName,url:this.appUrl}});this.clearHandshakeLoop()};e(),this.handshakeTimer=window.setInterval(e,300)}clearHandshakeLoop(){null!=this.handshakeTimer&&(clearInterval(this.handshakeTimer),this.handshakeTimer=void 0),this.handshakeDeadline=void 0}rejectInit(e){this.initDeferred&&(Object.assign(e,{code:"INITIALIZATION_FAILED",message:e.message}),this.initDeferred.reject(e),this.initDeferred=void 0)}startPopupClosedWatcher(){const e=this.popup;if(!e)return;const t=window.setInterval(()=>{(!e||e.closed)&&(clearInterval(t),this.destroy())},300);this.closeWatcherTimer=t}}var S=Object.defineProperty,A=(e,t,s)=>((e,t,s)=>t in e?S(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function b(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class D{constructor(e,t,s,n){this.appName=e,this.appUrl=t,this.targetOrigin=s,this.targetWindow=n,A(this,"sessionId",crypto.randomUUID()),A(this,"listening",!1),A(this,"walletReady",!1),A(this,"pending",new Map),A(this,"eventHandlers",new Set),A(this,"handshakeTimer"),A(this,"handshakeDeadline"),A(this,"initDeferred"),this.onWindowMessage=this.onWindowMessage.bind(this),this.attachListener()}async init(){if(!this.walletReady){if(this.initDeferred||(this.initDeferred=b()),this.listening||this.attachListener(),!this.targetWindow){const e=new Error("ThinTransport targetWindow is not available");throw this.rejectInit(e),e}return!this.walletReady&&null==this.handshakeTimer&&this.startHandshakeLoop(),this.initDeferred.promise}}destroy(){try{for(const e of this.eventHandlers)try{e({kind:"event",event:{type:"disconnected",reason:"destroyed"}})}catch{}this.detachListener(),this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.reject(new Error("Transport destroyed")),this.initDeferred=void 0);for(const[,e]of this.pending)e.reject(new Error("Transport destroyed"));this.pending.clear(),this.walletReady=!1}catch(e){}}async request(e,t,s){if("connect"===e&&await this.init(),!this.targetWindow){const t=b();if("status"===e){const e=crypto.randomUUID();this.pending.set(e,t),this.handleResponse({kind:"response",id:e,result:{connected:!1,walletVersion:void 0}})}return t.promise}const n=crypto.randomUUID(),i={kind:"request",id:n,method:e,params:t,sessionId:this.sessionId},r=b();return this.pending.set(n,r),this.post(i),r.promise}onEvent(e){return this.eventHandlers.add(e),()=>{this.eventHandlers.delete(e)}}attachListener(){this.listening||(window.addEventListener("message",this.onWindowMessage),this.listening=!0)}detachListener(){this.listening&&(window.removeEventListener("message",this.onWindowMessage),this.listening=!1)}post(e){try{if(!this.targetWindow)return;this.targetWindow.postMessage(e,this.targetOrigin)}catch(e){}}onWindowMessage(e){if(e.origin!==this.targetOrigin||e.source!==this.targetWindow)return;const t=e.data;if(t&&"object"==typeof t){if("event"===t.kind){for(const e of this.eventHandlers)e(t);return}if("handshake-ack"===t.kind&&t.ok)return void this.handleHandshakeAck();"response"===t.kind&&this.handleResponse(t)}}handleHandshakeAck(){this.walletReady=!0,this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.resolve(),this.initDeferred=void 0)}handleResponse(e){const t=this.pending.get(e.id);if(t)if(this.pending.delete(e.id),e.error){const s=Object.assign(new Error(e.error.message),{code:e.error.code,data:e.error.data});t.reject(s)}else t.resolve(e.result)}startHandshakeLoop(){this.handshakeDeadline=Date.now()+15e3;const e=()=>{if(!this.walletReady)return this.targetWindow?this.handshakeDeadline&&Date.now()>this.handshakeDeadline?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Handshake timed out"))):void this.post({kind:"handshake",sdkVersion:"0.0.0",sessionId:this.sessionId,dapp:{name:this.appName,url:this.appUrl}}):(this.clearHandshakeLoop(),void this.rejectInit(new Error("Target window unavailable before handshake")));this.clearHandshakeLoop()};e(),this.handshakeTimer=window.setInterval(e,300)}clearHandshakeLoop(){null!=this.handshakeTimer&&(clearInterval(this.handshakeTimer),this.handshakeTimer=void 0),this.handshakeDeadline=void 0}rejectInit(e){this.initDeferred&&(this.initDeferred.reject(e),this.initDeferred=void 0)}}var _=Object.defineProperty,C=(e,t,s)=>((e,t,s)=>t in e?_(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function N(t){try{const s=new URL(t).hostname;return s===e||s.endsWith(`.${e}`)}catch{return!1}}class O{constructor(e){var s,r,a;C(this,"transport"),C(this,"listeners",{});const o=null!=(s=e.dappName)?s:document.title||"Unknown dApp",h=null!=(r=e.dappUrl)?r:location.origin,d=null!=(a=e.network)?a:"mainnet";let c;switch(d){case"devnet":c=t;break;case"testmainnet":c=i;break;case"mainnet":c=n;break;default:throw new Error("Unsupported network: "+d)}const l=function(){var e;if(window.parent===window)return;const t=null==(e=window.location.ancestorOrigins)?void 0:e[0];if(t&&N(t))return t;if(document.referrer)try{const e=new URL(document.referrer).origin;return N(e)?e:void 0}catch{return}}();this.transport=l?new D(o,h,l,window.parent):new E(o,h,c),this.transport.onEvent(e=>{"event"===e.kind&&this.emit(e.event.type,e.event)})}async connect(){await this.transport.request("connect",void 0,!0)}async disconnect(){try{await this.transport.request("disconnect"),this.transport.destroy()}catch(e){}}status(){return this.transport.request("status")}getInstruments(){return this.transport.request("getInstruments")}getAccounts(e){return this.transport.request("getAccounts",{instrumentId:e})}send(e){return this.transport.request("send",e,!0)}createSwapOffer(e){return this.transport.request("createSwapOffer",e,!0)}signAndExecute(e){return this.transport.request("signAndExecute",e,!0)}signMessage(e,t){return this.transport.request("signMessage",{message:e,partyId:t},!0)}signAndExecutePreparedTransfer(e){return this.transport.request("signAndExecutePreparedTransfer",e,!0)}acknowledge(e){return this.transport.request("acknowledge",e,!0)}checkTxStatusById(e){return this.transport.request("checkTxStatusById",e)}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.listeners[e].delete(t)}emit(e,t){var s;for(const n of null!=(s=this.listeners[e])?s:[])n(t)}}const R={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},U="c8#provider_discovery";function L(e){const t={info:R,provider:e()};window.dispatchEvent(new CustomEvent(U,{detail:t}))}function H(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(U,t),()=>window.removeEventListener(U,t)}export{O as C8WalletProvider,T as HttpClient,r as LocalStorageHelper,L as announceC8Provider,H as onC8ProviderDiscovered};
1
+ const e="cantor8.tech",t="https://wallet.dev.digik.cantor8.tech",s="https://wallet-backend.dev.digik.cantor8.tech",n="https://wallet.cantor8.tech",i="https://wallet.main.digik.cantor8.tech";class r{static getItem(e){try{const t=localStorage.getItem(e);return t?JSON.parse(t):null}catch(e){return null}}static setItem(e,t){try{localStorage.setItem(e,JSON.stringify(t))}catch(e){}}static removeItem(e){try{localStorage.removeItem(e)}catch(e){}}}const a={TestCoin1:"TestCoin1",Amulet:"Canton Coin",CBTC:"CBTC",USDCx:"USDCx",CETH:"CETH"},o=e=>{var t;return"Amulet"===e?"Canton Coin":null!=(t=a[null!=e?e:""])?t:e},d={TestCoin1:"TestCoin1",Amulet:"CC",CBTC:"CBTC",USDCx:"USDCx"},h=e=>{var t;return"Amulet"===e?"CC":null!=(t=d[null!=e?e:""])?t:e};var c=Object.defineProperty,l=(e,t,s)=>((e,t,s)=>t in e?c(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const u=class e{constructor(){l(this,"appName"),l(this,"accounts",[]),l(this,"instruments",[]),l(this,"authToken",null),l(this,"isConnected",!1),l(this,"expireAt",null),l(this,"disconnectTimeoutId",null),this.load()}static getInstance(){return e.instance||(e.instance=new e),e.instance}setAppName(e){this.appName=e}getAppName(){return this.appName}setInstruments(e){this.instruments=e}getInstruments(){return this.instruments}setAccounts(e){this.accounts=e,this.instruments=e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:o(e.instrumentId),symbol:h(e.instrumentId)})))}getAccounts(){return this.accounts}setBearerToken(e,t){this.authToken=e,this.isConnected=!0,this.expireAt=t}getExpireAt(){return this.expireAt}setDisconnectTimeoutId(e){this.disconnectTimeoutId&&clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=e}getDisconnectTimeoutId(){return this.disconnectTimeoutId}getBearerToken(){return this.authToken}clear(){this.accounts=[],this.instruments=[],this.authToken=null,this.isConnected=!1,this.expireAt=null,this.disconnectTimeoutId&&(clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=null),r.removeItem(e.SESSION_KEY)}save(){r.setItem(e.SESSION_KEY,{authToken:this.authToken,accounts:this.accounts.map(({accountName:e,partyId:t,publicKey:s,validator:n})=>({accountName:e,partyId:t,publicKey:s,validator:n})),expireAt:this.expireAt})}setConnected(e){this.isConnected=e}getConnected(){return this.isConnected}hasStoredSession(){return!!r.getItem(e.SESSION_KEY)}load(){const t=r.getItem(e.SESSION_KEY);t&&(this.authToken=t.authToken,this.accounts=(t.accounts||[]).filter(e=>!!e.validator).map(e=>({...e,holdings:[]})),this.expireAt=t.expireAt||null)}};l(u,"instance"),l(u,"SESSION_KEY","c8-session");let p=u;var g=Object.defineProperty,f=(e,t,s)=>((e,t,s)=>t in e?g(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const m=class e{constructor(e=5e3){f(this,"pollingInterval",e),f(this,"events",new Map),f(this,"intervals",new Map),f(this,"handlerRegistry",new Map),this.restore()}static getInstance(t=5e3){return e.instance||(e.instance=new e(t)),e.instance}registerHandler(e,t){this.handlerRegistry.set(e,t),this.events.forEach((s,n)=>{s.event.type===e&&(this.stopPolling(n),s.handler=t,this.startPolling(n))})}add(e,t){const s=btoa(`${e}-${JSON.stringify(t)}`);this.events.has(s)&&this.remove(s);const n=this.handlerRegistry.get(e);if(!n)return;const i={key:s,type:e,params:t,createdAt:Date.now()};this.events.set(s,{event:i,handler:n}),this.persist(),this.startPolling(s)}remove(e){this.stopPolling(e),this.events.delete(e),this.persist()}startPolling(t){const s=this.events.get(t);if(!s)return;const{event:n,handler:i}=s,r=async()=>{try{if(n.createdAt&&Date.now()-n.createdAt>e.POLLING_TIMEOUT)return void this.remove(t);await i(n.params)&&this.remove(t)}catch(e){}};r();const a=window.setInterval(r,this.pollingInterval);this.intervals.set(t,a)}stopPolling(e){const t=this.intervals.get(e);void 0!==t&&(window.clearInterval(t),this.intervals.delete(e))}persist(){const t=Array.from(this.events.values()).map(e=>e.event);r.setItem(e.STORAGE_KEY,t)}restore(){const t=r.getItem(e.STORAGE_KEY);if(t&&Array.isArray(t)){const s=Date.now();t.forEach(t=>{if(t.createdAt&&s-t.createdAt>e.POLLING_TIMEOUT)return;const n=this.handlerRegistry.get(t.key);n?(this.events.set(t.key,{event:t,handler:n}),this.startPolling(t.key)):this.events.set(t.key,{event:t,handler:async()=>!1})})}}clear(){this.events.clear(),this.intervals.forEach(e=>window.clearInterval(e)),this.intervals.clear(),this.persist(),r.removeItem(e.STORAGE_KEY)}getEvents(){return Array.from(this.events.values()).map(e=>e.event)}};f(m,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),f(m,"type"),f(m,"instance"),f(m,"STORAGE_KEY","c8-polling-events"),f(m,"POLLING_TIMEOUT",3e5);let w=m;var v=Object.defineProperty;class y{constructor(e){((e,t,s)=>{((e,t,s)=>{t in e?v(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s})(e,t+"",s)})(this,"baseUrl"),this.baseUrl=e.endsWith("/")?e.slice(0,-1):e}async request(e,t={}){const s=p.getInstance().getBearerToken(),n=p.getInstance().getAppName(),i=new Headers(t.headers);s&&(i.set("Authorization",`Bearer ${s}`),i.set("X-App-Name",null!=n?n:"Unknown App")),i.set("x-feat-decimals","1");const r=await fetch(`${this.baseUrl}${e}`,{...t,headers:i});if(!r.ok)throw new Error(`HTTP error! status: ${r.status}`);return await r.json()}async getActiveContracts(e={}){var t,s,n;const i=null!=(t=e.limit)?t:1e4;if(!Number.isInteger(i)||i<1||i>2147483647)throw new Error("limit must be a positive 32-bit integer");if(void 0!==e.activeAtOffset&&("string"!=typeof e.activeAtOffset||!/^\d+$/.test(e.activeAtOffset)||BigInt(e.activeAtOffset)>BigInt("9223372036854775807")))throw new Error("activeAtOffset must be a nonnegative 64-bit integer string");if(void 0!==e.paginated&&"boolean"!=typeof e.paginated)throw new Error("paginated must be a boolean");if(void 0!==e.after&&("string"!=typeof e.after||!e.after))throw new Error("after must be a nonempty string");const r=new URLSearchParams({limit:String(i),include_created_event_blob:String(null!=(s=e.includeCreatedEventBlob)&&s),paginated:String(null==(n=e.paginated)||n)});for(const[t,s]of[["template_id",e.templateIds],["interface_id",e.interfaceIds]]){if(void 0!==s&&(!Array.isArray(s)||s.some(e=>"string"!=typeof e||!e)))throw new Error(`${t} filters must be nonempty strings`);for(const e of null!=s?s:[])r.append(t,e)}if(void 0!==e.includeCreatedEventBlob&&"boolean"!=typeof e.includeCreatedEventBlob)throw new Error("includeCreatedEventBlob must be a boolean");void 0!==e.activeAtOffset&&r.set("active_at_offset",e.activeAtOffset),void 0!==e.after&&r.set("after",e.after);const a=await this.scannerRequest("/contracts/active",e.partyId,"acting_party",r);if(!Array.isArray(a))throw new Error("Expected an active contracts array");return a}async scannerRequest(e,t,s,n){const i=p.getInstance(),r=i.getBearerToken(),a=i.getAccounts()[0],o=i.getExpireAt();if(!r||!a||null!=o&&o<=Date.now())throw new Error("Connect to the wallet before reading Scanner data");if(void 0!==t&&t!==a.partyId)throw new Error("Scanner reads are available only for the connected primary account");const d=a.validator.scannerApiUrl;if(!d)throw new Error("Scanner endpoint unavailable; disconnect and reconnect to the wallet");n.set(s,a.partyId);const h=await fetch(`${d.replace(/\/$/,"")}${e}?${n}`,{headers:{Authorization:`Bearer ${r}`}});if(!h.ok)throw new Error(`HTTP error! status: ${h.status}`);return h.json()}async getLedgerUpdates(e={}){var t,s;const n=null!=(t=e.limit)?t:500;if(!Number.isInteger(n)||n<1||n>1e3)throw new Error("limit must be an integer between 1 and 1000");const i=new URLSearchParams({limit:String(n)});if(void 0!==e.templateIds&&(!Array.isArray(e.templateIds)||e.templateIds.some(e=>"string"!=typeof e||!e)))throw new Error("template_id filters must be nonempty strings");for(const t of null!=(s=e.templateIds)?s:[])i.append("template_id",t);if(void 0!==e.cursor){const t="string"==typeof e.cursor&&/^(\d+):(-?\d+)$/.exec(e.cursor);if(!t||BigInt(t[1])>BigInt("9223372036854775807")||BigInt(t[2])<BigInt("-2147483648")||BigInt(t[2])>BigInt("2147483647"))throw new Error("cursor must be a nonnegative 64-bit offset and signed 32-bit node ID separated by a colon");i.set("after_offset",t[1]),i.set("after_node_id",t[2])}if(void 0!==e.eventType){if("created"!==e.eventType&&"exercised"!==e.eventType)throw new Error("eventType must be created or exercised");i.set("event_type",e.eventType)}if(void 0!==e.consuming){if("boolean"!=typeof e.consuming)throw new Error("consuming must be a boolean");i.set("consuming",String(e.consuming))}const r=await this.scannerRequest("/ledger-nodes",e.partyId,"party",i);if(!r||!Array.isArray(r.nodes)||"boolean"!=typeof r.complete)throw new Error("Expected a ledger updates page");return r}async getBalance(){return this.request("/api/balance")}async getTransferStatus(e){return this.request(`/api/transfer/status?command_id=${e}`)}async getContractsSetupState(){return this.request("/api/register/status_v2")}}var I=Object.defineProperty,T=(e,t,s)=>((e,t,s)=>t in e?I(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function E(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class k{constructor(e,r,a=t){let o;switch(T(this,"appName",e),T(this,"appUrl",r),T(this,"origin",a),T(this,"WINDOW_NAME","c8-wallet"),T(this,"WINDOW_WIDTH",475),T(this,"WINDOW_HEIGHT",762),T(this,"popup"),T(this,"sessionId",crypto.randomUUID()),T(this,"listening",!1),T(this,"walletReady",!1),T(this,"pending",new Map),T(this,"eventHandlers",new Set),T(this,"handshakeTimer"),T(this,"handshakeDeadline"),T(this,"closeWatcherTimer"),T(this,"pollingManager",w.getInstance()),T(this,"session",p.getInstance()),T(this,"initDeferred"),T(this,"httpClient"),this.onWindowMessage=this.onWindowMessage.bind(this),this.handleRestoreSession=this.handleRestoreSession.bind(this),this.handleTrackTxStatus=this.handleTrackTxStatus.bind(this),this.handleAccountUpdate=this.handleAccountUpdate.bind(this),this.session.setAppName(this.appName),this.attachListener(),this.origin){case t:o=s;break;case n:case i:o="https://wallet-backend.main.digik.cantor8.tech";break;default:o=s}this.httpClient=new y(o),this.pollingManager.registerHandler(w.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(w.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(w.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){this.session.hasStoredSession()&&this.pollingManager.add(w.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=this.session.getAccounts().find(t=>t.partyId===e.party_id);if(!t)return!1;const s=[{accountName:t.accountName,partyId:e.party_id,publicKey:t.publicKey,validator:t.validator,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(s),this.session.save()}return!0}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}async getTransferStatusById(e){try{const t=await this.httpClient.getTransferStatus(e);let s;switch(t.status){case"success":s="confirmed";break;case"failed":s="failed";break;default:s="pending"}return t.status=s,t}catch(e){return e instanceof Error&&e.message.includes("401")&&this.destroy(),null}}async handleTrackTxStatus(e){try{const t=await this.httpClient.getTransferStatus(e.txId);if(e.status!==t.status){let s;switch(t.status){case"success":s="confirmed";break;case"failed":s="failed";break;default:s="pending"}return this.emitSyntheticEvent({type:"txChanged",txId:e.txId,status:s}),e.status=t.status,this.pollingManager.persist(),"pending"!==t.status&&this.pollingManager.add(w.EVENT_TYPES.UPDATE_ACCOUNT,{txId:e.txId}),"success"===t.status||"failed"===t.status}}catch(t){if(t instanceof Error&&(t.message.includes("401")&&this.destroy(),t.message.includes("404")))return this.emitSyntheticEvent({type:"txChanged",txId:e.txId,status:"failed"}),!0}return!1}async handleRestoreSession(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=this.session.getAccounts().find(t=>t.partyId===e.party_id);if(!t)return!1;const s=[{accountName:t.accountName,partyId:e.party_id,publicKey:t.publicKey,validator:t.validator,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(s),this.session.save(),this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const n=this.session.getExpireAt();return n&&this.scheduleDisconnect(n),!0}}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}get WALLET_EMBEDDED(){return`${this.origin}/embedded/`}async init(e){var t;if(void 0!==this.popup&&(null==(t=this.popup)||!t.closed))return;if(this.initDeferred||(this.initDeferred=E()),this.listening||this.attachListener(),this.popup&&!this.popup.closed)return this.popup.focus(),null==this.handshakeTimer&&this.startHandshakeLoop(),this.initDeferred.promise;const s=new URL(null!=e?e:"",this.WALLET_EMBEDDED);if(this.popup=window.open(s,this.WINDOW_NAME,`width=${this.WINDOW_WIDTH},height=${this.WINDOW_HEIGHT}`),!this.popup){const e=new Error("Failed to open popup window");Object.assign(e,{code:"POPUP_BLOCKED",message:"browser blocked the popup window"}),this.rejectInit(e)}return this.startHandshakeLoop(),this.initDeferred.promise}emitSyntheticEvent(e){for(const t of this.eventHandlers)try{t({kind:"event",event:e})}catch(e){}}scheduleDisconnect(e){if(!e)return;const t=e-Date.now();if(t>0){const e=setTimeout(()=>{this.destroy("authToken expired")},t);this.session.setDisconnectTimeoutId(e)}else this.destroy("authToken expired")}destroy(e="destroyed"){try{this.emitSyntheticEvent({type:"disconnected",reason:e}),this.detachListener(),this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.reject(new Error("Transport destroyed")),this.initDeferred=void 0);for(const[,e]of this.pending)e.reject(new Error("Transport destroyed"));this.pending.clear(),this.popup&&!this.popup.closed&&this.popup.close(),this.popup=void 0,this.walletReady=!1,this.session.clear(),this.pollingManager.clear()}catch(e){}}async request(e,t,s){var n,i,r,a,o,d,h,c,l,u,p,g,f,m,w,v;const y=crypto.randomUUID(),I=E();this.pending.set(y,I);try{if("connect"===e){if(this.session.getBearerToken())return this.handleResponse({kind:"response",id:y,result:null}),I.promise;this.session.getBearerToken()||(this.walletReady=!1),await this.init()}if("send"===e&&(this.walletReady=!1,await this.init("confirmTransaction")),"createSwapOffer"===e&&(this.walletReady=!1,await this.init("confirmSwapOffer")),"signMessage"===e&&(this.walletReady=!1,await this.init("confirmSignMessage")),"signAndExecute"===e&&(this.walletReady=!1,await this.init("signAndExecute")),"status"===e)return this.handleResponse({kind:"response",id:y,result:{connected:this.session.getConnected(),walletVersion:void 0}}),I.promise;if(s&&(null==(n=this.popup)||n.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:y,result:{instruments:e}}),I.promise}if("getActiveContracts"===e){const e=await this.httpClient.getActiveContracts(t);return this.handleResponse({kind:"response",id:y,result:e}),I.promise}if("getLedgerUpdates"===e){const e=await this.httpClient.getLedgerUpdates(t);return this.handleResponse({kind:"response",id:y,result:e}),I.promise}if("getContractsSetupState"===e){const e=await this.httpClient.getContractsSetupState(),t={isRegistered:e.is_registered,isConfirmed:e.is_confirmed,isPreapprovalSet:e.is_preapproval_set,isPreapprovalInProgress:e.is_preapproval_in_progress,isAutoAcceptSet:e.is_auto_accept_set,isAutoAcceptInProgress:e.is_auto_accept_in_progress,isUsdcBridgeSet:e.is_usdc_bridge_set,isUsdcBridgeSetupInProgress:e.is_usdc_bridge_setup_in_progress,isWithdrawalDelegationSet:e.is_withdrawal_delegation_set,isWithdrawalDelegationInProgress:e.is_withdrawal_delegation_in_progress,isMergeDelegationSet:e.is_merge_delegation_set,isMergeDelegationInProgress:e.is_merge_delegation_in_progress};return this.handleResponse({kind:"response",id:y,result:t}),I.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:y,result:{accounts:e}}),I.promise}if("checkTxStatusById"===e){const e=t,s=await this.getTransferStatusById(null==e?void 0:e.txId);if(s){const e={status:s.status,transfer:{senderPartyId:null!=(r=null==(i=s.transfer)?void 0:i.party_id)?r:"",receiverPartyId:null!=(o=null==(a=s.transfer)?void 0:a.party_id2)?o:"",amount:Number(null!=(h=null==(d=s.transfer)?void 0:d.amount)?h:"0"),networkFees:Number(null!=(l=null==(c=s.transfer)?void 0:c.network_fees)?l:"0"),instrumentId:null!=(p=null==(u=s.transfer)?void 0:u.instrument_id)?p:"",txId:null!=(f=null==(g=s.transfer)?void 0:g.command_id)?f:"",created_at:null!=(w=null==(m=s.transfer)?void 0:m.created_at)?w:"",memo:null==(v=s.transfer)?void 0:v.reason}};this.handleResponse({kind:"response",id:y,result:e})}else this.handleResponse({kind:"response",id:y,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return I.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:y,result:null}),I.promise;const T={kind:"request",id:y,method:e,params:t,sessionId:this.sessionId};this.post(T)}catch(e){this.pending.delete(y),I.reject(e)}return I.promise}onEvent(e){return this.eventHandlers.add(e),()=>{this.eventHandlers.delete(e)}}attachListener(){this.listening||(window.addEventListener("message",this.onWindowMessage),this.listening=!0)}detachListener(){this.listening&&(window.removeEventListener("message",this.onWindowMessage),this.listening=!1)}post(e){try{if(!this.popup||this.popup.closed)return;this.popup.postMessage(e,this.origin)}catch(e){}}onWindowMessage(e){if(e.origin!==this.origin)return;const t=e.data;if(t&&"object"==typeof t){if("event"===t.kind){for(const e of this.eventHandlers)"txInitiated"===t.event.type&&this.pollingManager.add(w.EVENT_TYPES.TRACK_TX_STATUS,{txId:t.event.txId,status:"initiated"}),e(t);return}if("internal_event"===t.kind)return void this.pollingManager.add(t.event.type,{wop:"wopwop"});if("auth-flow"===t.kind&&(this.session.setBearerToken(t.token,t.expireAt),this.session.setAccounts(t.accounts),this.session.setInstruments(t.instruments),this.session.save(),this.scheduleDisconnect(t.expireAt)),"handshake-ack"===t.kind&&t.ok)return void this.handleHandshakeAck();"response"===t.kind&&this.handleResponse(t)}}handleHandshakeAck(){this.walletReady=!0,this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.resolve(),this.initDeferred=void 0)}handleResponse(e){const t=this.pending.get(e.id);if(t)if(this.pending.delete(e.id),e.error){const s=new Error(e.error.message||"Unknown Error");Object.assign(s,{code:e.error.code,data:e.error.data}),t.reject(s)}else t.resolve(e.result)}startHandshakeLoop(){this.handshakeDeadline=Date.now()+55e3;const e=()=>{if(!this.walletReady)return!this.popup||this.popup.closed?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Popup closed before handshake"))):this.handshakeDeadline&&Date.now()>this.handshakeDeadline?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Handshake timed out"))):void this.post({kind:"handshake",sdkVersion:"0.0.0",sessionId:this.sessionId,dapp:{name:this.appName,url:this.appUrl}});this.clearHandshakeLoop()};e(),this.handshakeTimer=window.setInterval(e,300)}clearHandshakeLoop(){null!=this.handshakeTimer&&(clearInterval(this.handshakeTimer),this.handshakeTimer=void 0),this.handshakeDeadline=void 0}rejectInit(e){this.initDeferred&&(Object.assign(e,{code:"INITIALIZATION_FAILED",message:e.message}),this.initDeferred.reject(e),this.initDeferred=void 0)}startPopupClosedWatcher(){const e=this.popup;if(!e)return;const t=window.setInterval(()=>{(!e||e.closed)&&(clearInterval(t),this.destroy())},300);this.closeWatcherTimer=t}}var S=Object.defineProperty,b=(e,t,s)=>((e,t,s)=>t in e?S(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function A(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class _{constructor(e,t,s,n){b(this,"appName",e),b(this,"appUrl",t),b(this,"targetOrigin",s),b(this,"targetWindow",n),b(this,"sessionId",crypto.randomUUID()),b(this,"listening",!1),b(this,"walletReady",!1),b(this,"pending",new Map),b(this,"eventHandlers",new Set),b(this,"handshakeTimer"),b(this,"handshakeDeadline"),b(this,"initDeferred"),this.onWindowMessage=this.onWindowMessage.bind(this),this.attachListener()}async init(){if(!this.walletReady){if(this.initDeferred||(this.initDeferred=A()),this.listening||this.attachListener(),!this.targetWindow){const e=new Error("ThinTransport targetWindow is not available");throw this.rejectInit(e),e}return!this.walletReady&&null==this.handshakeTimer&&this.startHandshakeLoop(),this.initDeferred.promise}}destroy(){try{for(const e of this.eventHandlers)try{e({kind:"event",event:{type:"disconnected",reason:"destroyed"}})}catch{}this.detachListener(),this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.reject(new Error("Transport destroyed")),this.initDeferred=void 0);for(const[,e]of this.pending)e.reject(new Error("Transport destroyed"));this.pending.clear(),this.walletReady=!1}catch(e){}}async request(e,t,s){if("connect"===e&&await this.init(),!this.targetWindow){const t=A();if("status"===e){const e=crypto.randomUUID();this.pending.set(e,t),this.handleResponse({kind:"response",id:e,result:{connected:!1,walletVersion:void 0}})}return t.promise}const n=crypto.randomUUID(),i={kind:"request",id:n,method:e,params:t,sessionId:this.sessionId},r=A();return this.pending.set(n,r),this.post(i),r.promise}onEvent(e){return this.eventHandlers.add(e),()=>{this.eventHandlers.delete(e)}}attachListener(){this.listening||(window.addEventListener("message",this.onWindowMessage),this.listening=!0)}detachListener(){this.listening&&(window.removeEventListener("message",this.onWindowMessage),this.listening=!1)}post(e){try{if(!this.targetWindow)return;this.targetWindow.postMessage(e,this.targetOrigin)}catch(e){}}onWindowMessage(e){if(e.origin!==this.targetOrigin||e.source!==this.targetWindow)return;const t=e.data;if(t&&"object"==typeof t){if("event"===t.kind){for(const e of this.eventHandlers)e(t);return}if("handshake-ack"===t.kind&&t.ok)return void this.handleHandshakeAck();"response"===t.kind&&this.handleResponse(t)}}handleHandshakeAck(){this.walletReady=!0,this.clearHandshakeLoop(),this.initDeferred&&(this.initDeferred.resolve(),this.initDeferred=void 0)}handleResponse(e){const t=this.pending.get(e.id);if(t)if(this.pending.delete(e.id),e.error){const s=Object.assign(new Error(e.error.message),{code:e.error.code,data:e.error.data});t.reject(s)}else t.resolve(e.result)}startHandshakeLoop(){this.handshakeDeadline=Date.now()+15e3;const e=()=>{if(!this.walletReady)return this.targetWindow?this.handshakeDeadline&&Date.now()>this.handshakeDeadline?(this.clearHandshakeLoop(),void this.rejectInit(new Error("Handshake timed out"))):void this.post({kind:"handshake",sdkVersion:"0.0.0",sessionId:this.sessionId,dapp:{name:this.appName,url:this.appUrl}}):(this.clearHandshakeLoop(),void this.rejectInit(new Error("Target window unavailable before handshake")));this.clearHandshakeLoop()};e(),this.handshakeTimer=window.setInterval(e,300)}clearHandshakeLoop(){null!=this.handshakeTimer&&(clearInterval(this.handshakeTimer),this.handshakeTimer=void 0),this.handshakeDeadline=void 0}rejectInit(e){this.initDeferred&&(this.initDeferred.reject(e),this.initDeferred=void 0)}}var D=Object.defineProperty,C=(e,t,s)=>((e,t,s)=>t in e?D(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function O(t){try{const s=new URL(t).hostname;return s===e||s.endsWith(`.${e}`)}catch{return!1}}class R{constructor(e){var s,r,a;C(this,"transport"),C(this,"listeners",{});const o=null!=(s=e.dappName)?s:document.title||"Unknown dApp",d=null!=(r=e.dappUrl)?r:location.origin,h=null!=(a=e.network)?a:"mainnet";let c;switch(h){case"devnet":c=t;break;case"testmainnet":c=i;break;case"mainnet":c=n;break;default:throw new Error("Unsupported network: "+h)}const l=function(){var e;if(window.parent===window)return;const t=null==(e=window.location.ancestorOrigins)?void 0:e[0];if(t&&O(t))return t;if(document.referrer)try{const e=new URL(document.referrer).origin;return O(e)?e:void 0}catch{return}}();this.transport=l?new _(o,d,l,window.parent):new k(o,d,c),this.transport.onEvent(e=>{"event"===e.kind&&this.emit(e.event.type,e.event)})}async connect(){await this.transport.request("connect",void 0,!0)}async disconnect(){try{await this.transport.request("disconnect"),this.transport.destroy()}catch(e){}}status(){return this.transport.request("status")}getContractsSetupState(){return this.transport.request("getContractsSetupState")}getInstruments(){return this.transport.request("getInstruments")}getActiveContracts(e={}){return this.transport.request("getActiveContracts",e)}getLedgerUpdates(e={}){return this.transport.request("getLedgerUpdates",e)}getAccounts(e){return this.transport.request("getAccounts",{instrumentId:e})}send(e){return this.transport.request("send",e,!0)}createSwapOffer(e){return this.transport.request("createSwapOffer",e,!0)}signAndExecute(e){return this.transport.request("signAndExecute",e,!0)}signMessage(e,t){return this.transport.request("signMessage",{message:e,partyId:t},!0)}signAndExecutePreparedTransfer(e){return this.transport.request("signAndExecutePreparedTransfer",e,!0)}acknowledge(e){return this.transport.request("acknowledge",e,!0)}checkTxStatusById(e){return this.transport.request("checkTxStatusById",e)}on(e,t){return this.listeners[e]||(this.listeners[e]=new Set),this.listeners[e].add(t),()=>this.listeners[e].delete(t)}emit(e,t){var s;for(const n of null!=(s=this.listeners[e])?s:[])n(t)}}const N={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},U="c8#provider_discovery";function L(e){const t={info:N,provider:e()};window.dispatchEvent(new CustomEvent(U,{detail:t}))}function x(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(U,t),()=>window.removeEventListener(U,t)}export{R as C8WalletProvider,y as HttpClient,r as LocalStorageHelper,L as announceC8Provider,x as onC8ProviderDiscovered};
@@ -1,4 +1,4 @@
1
- import { C8EventByType, C8EventType, Listener, MultiLegSwapSpecRequest } from "./types";
1
+ import { C8EventByType, C8EventType, Listener, GetActiveContractsInput, GetLedgerUpdatesInput, MultiLegSwapSpecRequest } from "./types";
2
2
  export declare class C8WalletProvider {
3
3
  private transport;
4
4
  private listeners;
@@ -13,7 +13,10 @@ export declare class C8WalletProvider {
13
13
  connected: boolean;
14
14
  walletVersion?: string;
15
15
  }>;
16
+ getContractsSetupState(): Promise<import("./types").RegisterStatusResponse>;
16
17
  getInstruments(): Promise<import("./types").InstrumentListPayload>;
18
+ getActiveContracts(input?: GetActiveContractsInput): Promise<import("./types").ActiveContractsPayload>;
19
+ getLedgerUpdates(input?: GetLedgerUpdatesInput): Promise<import("./types").LedgerUpdatesPayload>;
17
20
  getAccounts(instrumentId?: string): Promise<import("./types").AccountListPayload>;
18
21
  send(input: {
19
22
  senderPartyId: string;
@@ -1,6 +1,5 @@
1
1
  export type { Transport } from "./transports/Transport";
2
2
  export { WindowTransport } from "./transports/WindowTransport";
3
3
  export { ThinTransport } from "./transports/ThinTransport";
4
- export { IFrameTransport } from "./transports/IFrameTransport";
5
4
  export { WebViewTransport } from "./transports/WebViewTransport";
6
5
  export { WALLET_EMBED_URL, WALLET_ORIGIN_MAINNET, WALLET_ORIGIN_DEVNET } from "./transports/constants";
@@ -3,6 +3,6 @@ export declare const WALLET_BASE_DOMAIN = "cantor8.tech";
3
3
  export declare const WALLET_ORIGIN_DEVNET = "https://wallet.dev.digik.cantor8.tech";
4
4
  export declare const WALLET_API_DEVNET = "https://wallet-backend.dev.digik.cantor8.tech";
5
5
  export declare const WALLET_ORIGIN_MAINNET = "https://wallet.cantor8.tech";
6
- export declare const WALLET_API_MAINNET = "https://wallet-backend.main.cantor8.tech";
6
+ export declare const WALLET_API_MAINNET = "https://wallet-backend.main.digik.cantor8.tech";
7
7
  export declare const WALLET_ORIGIN_TEST_MAINNET = "https://wallet.main.digik.cantor8.tech";
8
8
  export declare const WALLET_EMBED_URL = "/embedded";
package/dist/types.d.ts CHANGED
@@ -80,12 +80,15 @@ export type InboundMessage = {
80
80
  payload: any;
81
81
  };
82
82
  };
83
- export type WalletMethod = "connect" | "disconnect" | "status" | "getInstruments" | "getAccounts" | "send" | "signMessage" | "signAndExecute" | "signAndExecutePreparedTransfer" | "acknowledge" | "checkTxStatusById" | "createSwapOffer";
83
+ export type WalletMethod = "connect" | "disconnect" | "status" | "getContractsSetupState" | "getInstruments" | "getActiveContracts" | "getLedgerUpdates" | "getAccounts" | "send" | "signMessage" | "signAndExecute" | "signAndExecutePreparedTransfer" | "acknowledge" | "checkTxStatusById" | "createSwapOffer";
84
84
  export interface WalletRequestPayloadMap {
85
85
  connect: undefined;
86
86
  disconnect: undefined;
87
87
  status: undefined;
88
+ getContractsSetupState: undefined;
88
89
  getInstruments: undefined;
90
+ getActiveContracts: GetActiveContractsInput;
91
+ getLedgerUpdates: GetLedgerUpdatesInput;
89
92
  getAccounts: {
90
93
  instrumentId?: string;
91
94
  };
@@ -182,6 +185,20 @@ export interface AppConfigPayload {
182
185
  update_url_android?: string | null;
183
186
  signups_guarded?: boolean;
184
187
  }
188
+ export interface RegisterStatusResponse {
189
+ isRegistered: boolean;
190
+ isConfirmed: boolean;
191
+ isPreapprovalSet: boolean;
192
+ isPreapprovalInProgress: boolean;
193
+ isAutoAcceptSet: boolean;
194
+ isAutoAcceptInProgress: boolean;
195
+ isUsdcBridgeSet: boolean;
196
+ isUsdcBridgeSetupInProgress: boolean;
197
+ isWithdrawalDelegationSet: boolean;
198
+ isWithdrawalDelegationInProgress: boolean;
199
+ isMergeDelegationSet: boolean;
200
+ isMergeDelegationInProgress: boolean;
201
+ }
185
202
  export interface AccountInfoHolding {
186
203
  instrumentId: string;
187
204
  balance: number;
@@ -190,6 +207,7 @@ export interface AccountInfoHolding {
190
207
  export interface ValidatorInfo {
191
208
  id: string;
192
209
  name: string;
210
+ scannerApiUrl?: string;
193
211
  }
194
212
  export interface AccountInfoPayload {
195
213
  accountName?: string;
@@ -227,6 +245,90 @@ export interface InstrumentInfoPayload {
227
245
  export interface InstrumentListPayload {
228
246
  instruments: InstrumentInfoPayload[];
229
247
  }
248
+ export interface GetLedgerUpdatesInput {
249
+ /** Defaults to the primary account; direct HTTP reads require that account. */
250
+ partyId?: string;
251
+ templateIds?: string[];
252
+ /** Scanner nextCursor, reused verbatim as an offset:nodeId string. */
253
+ cursor?: string;
254
+ eventType?: "created" | "exercised";
255
+ consuming?: boolean;
256
+ /** Integer from 1 to 1000; defaults to 500. */
257
+ limit?: number;
258
+ }
259
+ /** Scanner's page unchanged. Numeric payload fields use JavaScript precision. */
260
+ export interface LedgerUpdatesPayload {
261
+ nodes: LedgerNode[];
262
+ nextCursor?: string;
263
+ bounds?: {
264
+ floorOffset: number;
265
+ headOffset: number;
266
+ };
267
+ gap?: {
268
+ fromOffset: number;
269
+ toOffset: number;
270
+ reason?: string;
271
+ };
272
+ /** At Scanner's current fetch frontier, not the end of future ledger updates. */
273
+ complete: boolean;
274
+ }
275
+ export interface GetActiveContractsInput {
276
+ /** Defaults to the primary account; direct HTTP reads require that account. */
277
+ partyId?: string;
278
+ templateIds?: string[];
279
+ interfaceIds?: string[];
280
+ /** Nonnegative signed 64-bit decimal offset, kept as a string for precision. */
281
+ activeAtOffset?: string;
282
+ includeCreatedEventBlob?: boolean;
283
+ /** Positive integer; defaults to 10000. */
284
+ limit?: number;
285
+ /** Order by contract_id, including the first page; defaults to true. */
286
+ paginated?: boolean;
287
+ /** Resume after this contract_id, passed to Scanner unchanged. */
288
+ after?: string;
289
+ }
290
+ /** Scanner ledger node; optional witnesses distinguish unknown from empty. */
291
+ export interface LedgerNode {
292
+ offset: number;
293
+ nodeId: number;
294
+ updateId: string;
295
+ recordTime: string;
296
+ synchronizerId?: string;
297
+ commandId?: string;
298
+ workflowId?: string;
299
+ eventType: string;
300
+ consuming?: boolean;
301
+ acsDelta?: boolean;
302
+ lastDescendantNodeId?: number;
303
+ templateId?: string;
304
+ packageName?: string;
305
+ contractId?: string;
306
+ actingParties: string[];
307
+ witnessParties?: string[];
308
+ payload: Json;
309
+ }
310
+ /** Scanner contract row, retaining its original wire field names. */
311
+ export interface ScannerContract {
312
+ id: string;
313
+ contract_id: string;
314
+ template_id: string;
315
+ template_id_named: string;
316
+ interface_id?: string;
317
+ interface_id_wildcard?: string;
318
+ create_date: string;
319
+ create_event_id: string;
320
+ create_offset: number;
321
+ create_args: Json;
322
+ acting_parties: string[];
323
+ acting_dso: boolean;
324
+ acting_validator: boolean;
325
+ /** Base64-encoded created-event bytes, when requested. */
326
+ created_event_blob?: string;
327
+ archive_date: string;
328
+ archive_event_id?: string;
329
+ archive_offset?: number;
330
+ }
331
+ export type ActiveContractsPayload = ScannerContract[];
230
332
  export interface WalletResponsePayloadMap {
231
333
  connect: void;
232
334
  disconnect: void;
@@ -234,8 +336,11 @@ export interface WalletResponsePayloadMap {
234
336
  connected: boolean;
235
337
  walletVersion?: string;
236
338
  };
339
+ getContractsSetupState: RegisterStatusResponse;
237
340
  getInstruments: InstrumentListPayload;
238
341
  getAccounts: AccountListPayload;
342
+ getActiveContracts: ActiveContractsPayload;
343
+ getLedgerUpdates: LedgerUpdatesPayload;
239
344
  send: SubmitTransferResultPayload;
240
345
  signMessage: string;
241
346
  signAndExecute: void;
@@ -1,8 +1,13 @@
1
- import { PartyHoldingsApiResponse, TransferTransactionApiResponse } from "./HttpClient.types";
1
+ import { ActiveContractsPayload, GetActiveContractsInput, GetLedgerUpdatesInput, LedgerUpdatesPayload } from "../types";
2
+ import { PartyHoldingsApiResponse, RegisterStatusApiResponse, TransferTransactionApiResponse } from "./HttpClient.types";
2
3
  export declare class HttpClient {
3
4
  private readonly baseUrl;
4
5
  constructor(baseUrl: string);
5
6
  private request;
7
+ getActiveContracts(input?: GetActiveContractsInput): Promise<ActiveContractsPayload>;
8
+ private scannerRequest;
9
+ getLedgerUpdates(input?: GetLedgerUpdatesInput): Promise<LedgerUpdatesPayload>;
6
10
  getBalance(): Promise<PartyHoldingsApiResponse>;
7
11
  getTransferStatus(txId: string): Promise<TransferTransactionApiResponse>;
12
+ getContractsSetupState(): Promise<RegisterStatusApiResponse>;
8
13
  }
@@ -29,3 +29,17 @@ export interface PartyHoldingsApiResponse {
29
29
  party_id: string;
30
30
  holdings: Record<string, HoldingDetails>;
31
31
  }
32
+ export interface RegisterStatusApiResponse {
33
+ is_registered: boolean;
34
+ is_confirmed: boolean;
35
+ is_preapproval_set: boolean;
36
+ is_preapproval_in_progress: boolean;
37
+ is_auto_accept_set: boolean;
38
+ is_auto_accept_in_progress: boolean;
39
+ is_usdc_bridge_set: boolean;
40
+ is_usdc_bridge_setup_in_progress: boolean;
41
+ is_withdrawal_delegation_set: boolean;
42
+ is_withdrawal_delegation_in_progress: boolean;
43
+ is_merge_delegation_set: boolean;
44
+ is_merge_delegation_in_progress: boolean;
45
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cantor8/wallet-connect-sdk",
3
- "version": "0.5.0",
3
+ "version": "0.6.0",
4
4
  "description": "C8 Wallet Connect SDK for dApp developers: postMessage API to interact with C8 Wallet.",
5
5
  "author": "C8 / Cantor8",
6
6
  "license": "MIT",
@@ -47,7 +47,7 @@
47
47
  "@rollup/plugin-terser": "^1.0.0",
48
48
  "rollup": "^4.60.2",
49
49
  "rollup-plugin-esbuild": "^6.1.0",
50
- "typescript": "^6.0.3"
50
+ "typescript": "^7.0.2"
51
51
  },
52
52
  "publishConfig": {
53
53
  "registry": "https://registry.npmjs.org/"
@@ -1,46 +0,0 @@
1
- import { InboundMessage, WalletMethod } from "../types";
2
- import type { Transport } from "./Transport";
3
- /**
4
- * IFrameTransport embeds the wallet into the current page via an <iframe>
5
- * and communicates with it using window.postMessage. This avoids popups
6
- * and provides a persistent, same-tab experience.
7
- */
8
- export declare class IFrameTransport implements Transport {
9
- private readonly dappName;
10
- private readonly dappUrl;
11
- private readonly origin;
12
- /**
13
- * Optional target where the iframe should be appended. If a function is provided
14
- * it will be called at init-time to resolve the element. Defaults to document.body.
15
- */
16
- private readonly appendTarget?;
17
- private iframe?;
18
- private readonly sessionId;
19
- private listening;
20
- private walletReady;
21
- private readonly pending;
22
- private readonly eventHandlers;
23
- private handshakeTimer?;
24
- private handshakeDeadline?;
25
- private initDeferred?;
26
- constructor(dappName: string, dappUrl: string, origin?: string,
27
- /**
28
- * Optional target where the iframe should be appended. If a function is provided
29
- * it will be called at init-time to resolve the element. Defaults to document.body.
30
- */
31
- appendTarget?: (Element | (() => Element | null)) | undefined);
32
- private get WALLET_EMBEDDED();
33
- init(): Promise<void>;
34
- destroy(): void;
35
- request<M extends WalletMethod, T = unknown>(method: M, params?: unknown, _forceShow?: boolean): Promise<T>;
36
- onEvent(cb: (msg: InboundMessage) => void): () => void;
37
- private attachListener;
38
- private detachListener;
39
- private post;
40
- private onWindowMessage;
41
- private handleHandshakeAck;
42
- private handleResponse;
43
- private startHandshakeLoop;
44
- private clearHandshakeLoop;
45
- private rejectInit;
46
- }