@cantor8/wallet-connect-sdk 0.5.1 → 0.7.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
@@ -27,6 +27,24 @@ const c8 = new C8WalletProvider({
27
27
  });
28
28
  ```
29
29
 
30
+ After approval, the wallet supplies `validator.backendApiUrl` alongside
31
+ `validator.scannerApiUrl` in the account metadata. The SDK persists both URLs with
32
+ the session and uses each selected account's backend URL for balance, transfer
33
+ status, and contract setup requests, including after a page reload. Older sessions
34
+ without `backendApiUrl` must disconnect and reconnect.
35
+
36
+ The approval message supplies `authToken` on each account, with no top-level
37
+ token. Account tokens are persisted with the session; backend requests use the
38
+ selected account's token and Scanner requests use the primary account's token.
39
+ Sessions stored with a legacy shared token must
40
+ reconnect. The approval message's `expireAt` still applies to the whole session.
41
+
42
+ Balance refresh and session restore fetch balances for all connected accounts.
43
+ `HttpClient.getBalance()` returns an array of balance responses in account order.
44
+ `getTransferStatus(txId, partyId?)` and `getContractsSetupState(partyId?)` select
45
+ the matching connected account, defaulting to the primary account when omitted.
46
+ An unknown party ID is rejected without sending a request.
47
+
30
48
  ## Events
31
49
 
32
50
  You can subscribe to wallet events using `c8.on()`:
@@ -62,6 +80,11 @@ console.log("Accounts", accounts);
62
80
 
63
81
  const senderPartyId = accounts.accounts[0]?.partyId;
64
82
 
83
+ // Registration and validator-managed contract setup state
84
+ // Return type: PartyContractSetupResponse
85
+ const contractsSetupState = await c8.getContractsSetupState();
86
+ console.log("Contracts setup state", contractsSetupState);
87
+
65
88
  const senderHoldingInstrumentId =
66
89
  accounts.accounts[0]?.holdings[0]?.instrumentId || firstInstrumentId;
67
90
 
@@ -128,15 +151,75 @@ console.log("Signature", signature);
128
151
  | `connect()` | None | `Promise<void>` |
129
152
  | `disconnect()` | None | `Promise<void>` |
130
153
  | `status()` | None | `Promise<{ connected: boolean; walletVersion?: string }>` |
154
+ | `getContractsSetupState()` | `partyId?: string` | `Promise<PartyContractSetupResponse>` |
131
155
  | `getInstruments()` | None | `Promise<InstrumentListPayload>` |
156
+ | `getActiveContracts()` | `input?: GetActiveContractsInput` | `Promise<ActiveContractsPayload>` |
132
157
  | `getAccounts()` | `instrumentId?: string` | `Promise<AccountListPayload>` |
133
158
  | `send()` | `input: SendInput` | `Promise<SubmitTransferResultPayload>` |
134
159
  | `createSwapOffer()` | `input: { partyId, swap, commandId? }` | `Promise<SubmitTransferResultPayload>` |
135
160
  | `signMessage()` | `message: string, partyId?: string` | `Promise<string>` |
136
161
  | `signAndExecute()` | `input: SignAndExecuteInput` | `Promise<void>` |
137
- | `checkTxStatusById()` | `input: { txId: string }` | `Promise<TransferStatusResponsePayload>` |
162
+ | `checkTxStatusById()` | `input: { txId: string; partyId?: string }` | `Promise<TransferStatusResponsePayload>` |
138
163
  | `on()` | `event: T, cb: Listener<C8EventByType<T>>` | `() => boolean` |
139
164
 
165
+ ### `getContractsSetupState()`
166
+
167
+ Returns the authenticated account's contract setup transactions, including all
168
+ statuses, from the wallet backend's `/api/register/contract-setup` endpoint:
169
+
170
+ ```ts
171
+ const state = await c8.getContractsSetupState();
172
+ // Or select a connected account: await c8.getContractsSetupState(partyId);
173
+
174
+ console.log("Party:", state.partyId);
175
+ for (const contract of state.contracts) {
176
+ console.log(contract.code, contract.status, contract.contractId);
177
+ }
178
+ ```
179
+
180
+ The returned `PartyContractSetupResponse` contains `partyId` and a `contracts`
181
+ array. Each `ContractSetupItem` includes `id`, `code`, `partyId`, `commandId`,
182
+ `contractId`, `status`, `submittedAt`, and `completedAt`. The contract ID and
183
+ timestamps may be `null`; statuses are returned as supplied by the backend.
184
+
185
+ This replaces the previous registration-flag response (`RegisterStatusResponse`).
186
+ Consumers must read `contracts` instead of the old `is...` flags. Embedded wallet
187
+ hosts must also return this response shape for the `getContractsSetupState` RPC.
188
+
189
+ ### `getActiveContracts()`
190
+
191
+ Reads Scanner ACS using the Wallet App's authenticated account:
192
+
193
+ ```ts
194
+ const contracts = await c8.getActiveContracts({
195
+ templateIds: ["package-id:Module:Template"],
196
+ includeCreatedEventBlob: true,
197
+ limit: 10000,
198
+ });
199
+ console.log(contracts);
200
+ ```
201
+
202
+ For direct popup-provider reads, optional `partyId` must match the connected primary
203
+ account; the stored token belongs to that account. Embedded Wallet App reads can
204
+ select an account owned by the wallet. The primary account is used by default.
205
+ `interfaceIds` filters interfaces. `activeAtOffset` requests a
206
+ point-in-time snapshot using a nonnegative signed 64-bit decimal **string**.
207
+ Offsets beyond Scanner ingestion are rejected. `limit` must be a positive integer
208
+ and defaults to 10000. `paginated` defaults to `true` so the first page is ordered
209
+ by `contract_id` even when `after` is absent. Pass a nonempty `after` contract ID
210
+ unchanged to request rows after it; explicit `paginated: false` is also forwarded.
211
+ Scanner returns at most `limit` rows without completeness metadata. Base contract
212
+ and interface rows can share a `contract_id`; if the limit splits that group,
213
+ the next `after` request skips its remaining rows. These parameters do not
214
+ guarantee complete traversal.
215
+
216
+ The result is the Scanner contract array with its original field names and
217
+ created-event blobs. JSON numbers use normal JavaScript numeric precision.
218
+ After `connect()`, the popup provider calls the primary account's Scanner endpoint
219
+ directly with the stored wallet token, even after the popup closes. No additional
220
+ token is supplied to this method. Older sessions missing `validator.scannerApiUrl`
221
+ must disconnect and reconnect. Embedded providers retain the existing Wallet App RPC.
222
+
140
223
  ### `send()` Input
141
224
 
142
225
  ```ts
@@ -228,7 +311,7 @@ Use `c8.on(eventType, callback)` to listen for changes emitted by the wallet.
228
311
  | ------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
229
312
  | `connected` | `meta?: Json` | Fired when the wallet successfully connects. |
230
313
  | `disconnected` | `reason?: string`, `meta?: Json` | Fired when the session disconnects. |
231
- | `txInitiated` | `txId?: string`, `meta?: Json` | Fired when a transaction request is initiated. |
314
+ | `txInitiated` | `txId?: string`, `partyId?: string`, `meta?: Json` | Fired when a transaction request is initiated. |
232
315
  | `txChanged` | `txId: string`, `status: "pending" \| "confirmed" \| "failed" \| string`, `meta?: Json` | Fired when a transaction's completion status updates. |
233
316
  | `accountChanged` | `accounts: AccountInfoPayload[]`, `meta?: Json` | Fired when internal account asset holdings scale or modify. |
234
317
  | `themeChanged` | `theme: "dark" \| "light"`, `meta?: Json` | Fired when the wallet interface changes its UI display theme. |
@@ -249,3 +332,37 @@ unsubscribe();
249
332
  ## License
250
333
 
251
334
  MIT
335
+
336
+ ### Ledger updates
337
+
338
+ `getLedgerUpdates` reads one page from Scanner's authenticated `/ledger-nodes`
339
+ feed. External providers use direct HTTP with the stored session token and the
340
+ primary account’s configured Scanner URL, including after the wallet popup closes.
341
+ Embedded providers use the existing App RPC and can select another owned account.
342
+ Like ACS, old sessions without Scanner metadata must disconnect and reconnect.
343
+
344
+ ```ts
345
+ const page = await provider.getLedgerUpdates({
346
+ partyId, // optional; defaults to the primary wallet account
347
+ templateIds: ["package:Module:Template"],
348
+ limit: 500, // 1–1000
349
+ });
350
+ const nextPage = page.nextCursor
351
+ ? await provider.getLedgerUpdates({ partyId, cursor: page.nextCursor,
352
+ templateIds: ["package:Module:Template"] })
353
+ : undefined;
354
+ ```
355
+
356
+ The result is Scanner's `{ nodes, nextCursor?, bounds?, gap?, complete }` page,
357
+ with typed `LedgerNode` fields and unchanged JSON event payloads. Optional `eventType` (`created` or `exercised`) and
358
+ `consuming` filters pass through. Reuse `nextCursor` verbatim with the same
359
+ filters: it retains exact offsets even beyond JavaScript's safe integer range.
360
+ To start at an offset, use `"<offset>:-2147483648"`. Other numeric JSON fields
361
+ have ordinary JavaScript precision.
362
+
363
+ An empty page can still advance the cursor. `complete` means the current Scanner
364
+ fetch frontier was reached; new updates may arrive later. `gap` reports lost
365
+ history and must not be treated as an empty successful history. Requests before
366
+ retained history fail. This is a paginated Scanner feed, not Ledger's streaming
367
+ `/v2/updates` response. Scanner must enable this feed and support user-token party
368
+ 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.digik.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="0.7.0";class n{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 i={TestCoin1:"TestCoin1",Amulet:"Canton Coin",CBTC:"CBTC",USDCx:"USDCx",CETH:"CETH"},r=e=>{var t;return"Amulet"===e?"Canton Coin":null!=(t=i[null!=e?e:""])?t:e},a={TestCoin1:"TestCoin1",Amulet:"CC",CBTC:"CBTC",USDCx:"USDCx"},o=e=>{var t;return"Amulet"===e?"CC":null!=(t=a[null!=e?e:""])?t:e};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);const h=class e{constructor(){c(this,"appName"),c(this,"accounts",[]),c(this,"instruments",[]),c(this,"isConnected",!1),c(this,"expireAt",null),c(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){const t=new Set;this.instruments=e.filter(e=>!t.has(e.instrumentId)&&(t.add(e.instrumentId),!0))}getInstruments(){return this.instruments}setAccounts(e){this.accounts=e,this.setInstruments(e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:r(e.instrumentId),symbol:o(e.instrumentId)}))))}getAccounts(){return this.accounts}setExpireAt(e){this.expireAt=e}getExpireAt(){return this.expireAt}setDisconnectTimeoutId(e){this.disconnectTimeoutId&&clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=e}getDisconnectTimeoutId(){return this.disconnectTimeoutId}clear(){this.accounts=[],this.instruments=[],this.isConnected=!1,this.expireAt=null,this.disconnectTimeoutId&&(clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=null),n.removeItem(e.SESSION_KEY)}save(){n.setItem(e.SESSION_KEY,{accounts:this.accounts.map(({accountName:e,authToken:t,partyId:s,publicKey:n,validator:i})=>({accountName:e,authToken:t,partyId:s,publicKey:n,validator:i})),expireAt:this.expireAt})}setConnected(e){this.isConnected=e}getConnected(){return this.isConnected}hasStoredSession(){return!!n.getItem(e.SESSION_KEY)}load(){const t=n.getItem(e.SESSION_KEY);t&&(this.accounts=(t.accounts||[]).filter(e=>!!e.validator&&"string"==typeof e.authToken&&!!e.authToken).map(e=>({...e,holdings:[]})),this.expireAt=t.expireAt||null)}};c(h,"instance"),c(h,"SESSION_KEY","c8-session");let l=h;var u=Object.defineProperty,p=(e,t,s)=>((e,t,s)=>t in e?u(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const g=class e{constructor(e=5e3){p(this,"pollingInterval",e),p(this,"events",new Map),p(this,"intervals",new Map),p(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);n.setItem(e.STORAGE_KEY,t)}restore(){const t=n.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(),n.removeItem(e.STORAGE_KEY)}getEvents(){return Array.from(this.events.values()).map(e=>e.event)}};p(g,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),p(g,"type"),p(g,"instance"),p(g,"STORAGE_KEY","c8-polling-events"),p(g,"POLLING_TIMEOUT",3e5);let f=g;class m{async request(e,t,s={}){const n=l.getInstance(),i=n.getAccounts(),r=void 0===t?i[0]:i.find(e=>e.partyId===t);if(!r)throw new Error(void 0===t?"Connect to the wallet before making backend requests":"Requested party is not a connected account");const a=null==r?void 0:r.validator.backendApiUrl;if(!a)throw new Error("Backend endpoint unavailable; disconnect and reconnect to the wallet");const o=null==r?void 0:r.authToken;if(!o)throw new Error("Connect to the wallet before making backend requests");const d=n.getAppName(),c=new Headers(s.headers);o&&(c.set("Authorization",`Bearer ${o}`),c.set("X-App-Name",null!=d?d:"Unknown App")),c.set("x-feat-decimals","1");const h=await fetch(`${a.replace(/\/$/,"")}${e}`,{...s,headers:c});if(!h.ok)throw new Error(`HTTP error! status: ${h.status}`);return await h.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=l.getInstance(),r=i.getAccounts()[0],a=null==r?void 0:r.authToken,o=i.getExpireAt();if(!a||!r||null!=o&&o<=Date.now())throw new Error("Connect to the wallet before reading Scanner data");if(void 0!==t&&t!==r.partyId)throw new Error("Scanner reads are available only for the connected primary account");const d=r.validator.scannerApiUrl;if(!d)throw new Error("Scanner endpoint unavailable; disconnect and reconnect to the wallet");n.set(s,r.partyId);const c=await fetch(`${d.replace(/\/$/,"")}${e}?${n}`,{headers:{Authorization:`Bearer ${a}`}});if(!c.ok)throw new Error(`HTTP error! status: ${c.status}`);return c.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 Promise.all(l.getInstance().getAccounts().map(async e=>{const t=await this.request("/api/balance",e.partyId);if(t.party_id!==e.partyId||!t.holdings)throw new Error("Unexpected balance response for connected account");return t}))}async getTransferStatus(e,t){return this.request(`/api/transfer/status?command_id=${encodeURIComponent(e)}`,t)}async getContractsSetupState(e){return this.request("/api/register/contract-setup",e)}}var w=Object.defineProperty,v=(e,t,s)=>((e,t,s)=>t in e?w(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function y(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class I{constructor(e,s,n=t){v(this,"appName",e),v(this,"appUrl",s),v(this,"origin",n),v(this,"WINDOW_NAME","c8-wallet"),v(this,"WINDOW_WIDTH",475),v(this,"WINDOW_HEIGHT",762),v(this,"popup"),v(this,"sessionId",crypto.randomUUID()),v(this,"listening",!1),v(this,"walletReady",!1),v(this,"pending",new Map),v(this,"eventHandlers",new Set),v(this,"handshakeTimer"),v(this,"handshakeDeadline"),v(this,"closeWatcherTimer"),v(this,"pollingManager",f.getInstance()),v(this,"session",l.getInstance()),v(this,"initDeferred"),v(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.httpClient=new m,this.pollingManager.registerHandler(f.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(f.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(f.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){var e;this.session.hasStoredSession()&&null!=(e=this.session.getAccounts()[0])&&e.authToken&&this.pollingManager.add(f.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(!e.length)return!1;const t=this.session.getAccounts().map(t=>{const s=e.find(e=>e.party_id===t.partyId);return s?{...t,holdings:Object.entries(s.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}:t});return this.session.setAccounts(t),this.session.save(),!0}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}async getTransferStatusById(e,t){try{const s=await this.httpClient.getTransferStatus(e,t);let n;switch(s.status){case"success":n="confirmed";break;case"failed":n="failed";break;default:n="pending"}return s.status=n,s}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,e.partyId);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(f.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{if(await this.handleAccountUpdate()){this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const e=this.session.getExpireAt();return e&&this.scheduleDisconnect(e),!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=y()),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,c,h,l,u,p,g,f,m,w,v,I;const E=crypto.randomUUID(),T=y();this.pending.set(E,T);try{if("connect"===e){if(null!=(n=this.session.getAccounts()[0])&&n.authToken)return this.handleResponse({kind:"response",id:E,result:null}),T.promise;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:E,result:{connected:this.session.getConnected(),walletVersion:void 0}}),T.promise;if(s&&(null==(i=this.popup)||i.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:E,result:{instruments:e}}),T.promise}if("getActiveContracts"===e){const e=await this.httpClient.getActiveContracts(t);return this.handleResponse({kind:"response",id:E,result:e}),T.promise}if("getLedgerUpdates"===e){const e=await this.httpClient.getLedgerUpdates(t);return this.handleResponse({kind:"response",id:E,result:e}),T.promise}if("getContractsSetupState"===e){const e=t,s=await this.httpClient.getContractsSetupState(null==e?void 0:e.partyId),n={partyId:s.party_id,contracts:s.contracts.map(e=>({id:e.id,code:e.code,partyId:e.party_id,commandId:e.command_id,contractId:e.contract_id,status:e.status,submittedAt:e.submitted_at,completedAt:e.completed_at}))};return this.handleResponse({kind:"response",id:E,result:n}),T.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:E,result:{accounts:e}}),T.promise}if("checkTxStatusById"===e){const e=t,s=await this.getTransferStatusById(null==e?void 0:e.txId,null==e?void 0:e.partyId);if(s){const e={status:s.status,transfer:{senderPartyId:null!=(a=null==(r=s.transfer)?void 0:r.party_id)?a:"",receiverPartyId:null!=(d=null==(o=s.transfer)?void 0:o.party_id2)?d:"",amount:Number(null!=(h=null==(c=s.transfer)?void 0:c.amount)?h:"0"),networkFees:Number(null!=(u=null==(l=s.transfer)?void 0:l.network_fees)?u:"0"),instrumentId:null!=(g=null==(p=s.transfer)?void 0:p.instrument_id)?g:"",txId:null!=(m=null==(f=s.transfer)?void 0:f.command_id)?m:"",created_at:null!=(v=null==(w=s.transfer)?void 0:w.created_at)?v:"",memo:null==(I=s.transfer)?void 0:I.reason}};this.handleResponse({kind:"response",id:E,result:e})}else this.handleResponse({kind:"response",id:E,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return T.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:E,result:null}),T.promise;const y={kind:"request",id:E,method:e,params:t,sessionId:this.sessionId};this.post(y)}catch(e){this.pending.delete(E),T.reject(e)}return T.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){var t;if(e.origin!==this.origin)return;const s=e.data;if(s&&"object"==typeof s){if("event"===s.kind){for(const e of this.eventHandlers)"txInitiated"===s.event.type&&this.pollingManager.add(f.EVENT_TYPES.TRACK_TX_STATUS,{txId:s.event.txId,partyId:s.event.partyId,status:"initiated"}),e(s);return}if("internal_event"===s.kind)return void this.pollingManager.add(s.event.type,{wop:"wopwop"});if("auth-flow"===s.kind&&(this.session.setAccounts(s.accounts),this.session.setExpireAt(s.expireAt),this.session.setConnected(!(null==(t=s.accounts[0])||!t.authToken)),this.session.setInstruments(s.instruments),this.session.save(),this.scheduleDisconnect(s.expireAt)),"handshake-ack"===s.kind&&s.ok)return void this.handleHandshakeAck();"response"===s.kind&&this.handleResponse(s)}}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:s,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 E=Object.defineProperty,T=(e,t,s)=>((e,t,s)=>t in e?E(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function k(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class A{constructor(e,t,s,n){T(this,"appName",e),T(this,"appUrl",t),T(this,"targetOrigin",s),T(this,"targetWindow",n),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,"initDeferred"),this.onWindowMessage=this.onWindowMessage.bind(this),this.attachListener()}async init(){if(!this.walletReady){if(this.initDeferred||(this.initDeferred=k()),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=k();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=k();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:s,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 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 C(t){try{const s=new URL(t).hostname;return s===e||s.endsWith(`.${e}`)}catch{return!1}}const D={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},_="c8#provider_discovery";exports.C8WalletProvider=class{constructor(e){var s,n,i;b(this,"transport"),b(this,"listeners",{});const r=null!=(s=e.dappName)?s:document.title||"Unknown dApp",a=null!=(n=e.dappUrl)?n:location.origin,o=null!=(i=e.network)?i:"mainnet";let d;switch(o){case"local":d="http://localhost:8081";break;case"devnet":d=t;break;case"testmainnet":d="https://wallet.main.digik.cantor8.tech";break;case"mainnet":d="https://wallet.cantor8.tech";break;default:throw new Error("Unsupported network: "+o)}const c=function(){var e;if(window.parent===window)return;const t=null==(e=window.location.ancestorOrigins)?void 0:e[0];if(t&&C(t))return t;if(document.referrer)try{const e=new URL(document.referrer).origin;return C(e)?e:void 0}catch{return}}();this.transport=c?new A(r,a,c,window.parent):new I(r,a,d),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(e){return this.transport.request("getContractsSetupState",void 0===e?void 0:{partyId:e})}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=m,exports.LocalStorageHelper=n,exports.announceC8Provider=function(e){const t={info:D,provider:e()};window.dispatchEvent(new CustomEvent(_,{detail:t}))},exports.onC8ProviderDiscovered=function(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(_,t),()=>window.removeEventListener(_,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.digik.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="0.7.0";class n{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 i={TestCoin1:"TestCoin1",Amulet:"Canton Coin",CBTC:"CBTC",USDCx:"USDCx",CETH:"CETH"},r=e=>{var t;return"Amulet"===e?"Canton Coin":null!=(t=i[null!=e?e:""])?t:e},a={TestCoin1:"TestCoin1",Amulet:"CC",CBTC:"CBTC",USDCx:"USDCx"},o=e=>{var t;return"Amulet"===e?"CC":null!=(t=a[null!=e?e:""])?t:e};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);const h=class e{constructor(){c(this,"appName"),c(this,"accounts",[]),c(this,"instruments",[]),c(this,"isConnected",!1),c(this,"expireAt",null),c(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){const t=new Set;this.instruments=e.filter(e=>!t.has(e.instrumentId)&&(t.add(e.instrumentId),!0))}getInstruments(){return this.instruments}setAccounts(e){this.accounts=e,this.setInstruments(e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:r(e.instrumentId),symbol:o(e.instrumentId)}))))}getAccounts(){return this.accounts}setExpireAt(e){this.expireAt=e}getExpireAt(){return this.expireAt}setDisconnectTimeoutId(e){this.disconnectTimeoutId&&clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=e}getDisconnectTimeoutId(){return this.disconnectTimeoutId}clear(){this.accounts=[],this.instruments=[],this.isConnected=!1,this.expireAt=null,this.disconnectTimeoutId&&(clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=null),n.removeItem(e.SESSION_KEY)}save(){n.setItem(e.SESSION_KEY,{accounts:this.accounts.map(({accountName:e,authToken:t,partyId:s,publicKey:n,validator:i})=>({accountName:e,authToken:t,partyId:s,publicKey:n,validator:i})),expireAt:this.expireAt})}setConnected(e){this.isConnected=e}getConnected(){return this.isConnected}hasStoredSession(){return!!n.getItem(e.SESSION_KEY)}load(){const t=n.getItem(e.SESSION_KEY);t&&(this.accounts=(t.accounts||[]).filter(e=>!!e.validator&&"string"==typeof e.authToken&&!!e.authToken).map(e=>({...e,holdings:[]})),this.expireAt=t.expireAt||null)}};c(h,"instance"),c(h,"SESSION_KEY","c8-session");let l=h;var u=Object.defineProperty,p=(e,t,s)=>((e,t,s)=>t in e?u(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const g=class e{constructor(e=5e3){p(this,"pollingInterval",e),p(this,"events",new Map),p(this,"intervals",new Map),p(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);n.setItem(e.STORAGE_KEY,t)}restore(){const t=n.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(),n.removeItem(e.STORAGE_KEY)}getEvents(){return Array.from(this.events.values()).map(e=>e.event)}};p(g,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),p(g,"type"),p(g,"instance"),p(g,"STORAGE_KEY","c8-polling-events"),p(g,"POLLING_TIMEOUT",3e5);let f=g;class m{async request(e,t,s={}){const n=l.getInstance(),i=n.getAccounts(),r=void 0===t?i[0]:i.find(e=>e.partyId===t);if(!r)throw new Error(void 0===t?"Connect to the wallet before making backend requests":"Requested party is not a connected account");const a=null==r?void 0:r.validator.backendApiUrl;if(!a)throw new Error("Backend endpoint unavailable; disconnect and reconnect to the wallet");const o=null==r?void 0:r.authToken;if(!o)throw new Error("Connect to the wallet before making backend requests");const d=n.getAppName(),c=new Headers(s.headers);o&&(c.set("Authorization",`Bearer ${o}`),c.set("X-App-Name",null!=d?d:"Unknown App")),c.set("x-feat-decimals","1");const h=await fetch(`${a.replace(/\/$/,"")}${e}`,{...s,headers:c});if(!h.ok)throw new Error(`HTTP error! status: ${h.status}`);return await h.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=l.getInstance(),r=i.getAccounts()[0],a=null==r?void 0:r.authToken,o=i.getExpireAt();if(!a||!r||null!=o&&o<=Date.now())throw new Error("Connect to the wallet before reading Scanner data");if(void 0!==t&&t!==r.partyId)throw new Error("Scanner reads are available only for the connected primary account");const d=r.validator.scannerApiUrl;if(!d)throw new Error("Scanner endpoint unavailable; disconnect and reconnect to the wallet");n.set(s,r.partyId);const c=await fetch(`${d.replace(/\/$/,"")}${e}?${n}`,{headers:{Authorization:`Bearer ${a}`}});if(!c.ok)throw new Error(`HTTP error! status: ${c.status}`);return c.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 Promise.all(l.getInstance().getAccounts().map(async e=>{const t=await this.request("/api/balance",e.partyId);if(t.party_id!==e.partyId||!t.holdings)throw new Error("Unexpected balance response for connected account");return t}))}async getTransferStatus(e,t){return this.request(`/api/transfer/status?command_id=${encodeURIComponent(e)}`,t)}async getContractsSetupState(e){return this.request("/api/register/contract-setup",e)}}var w=Object.defineProperty,v=(e,t,s)=>((e,t,s)=>t in e?w(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function y(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class I{constructor(e,s,n=t){v(this,"appName",e),v(this,"appUrl",s),v(this,"origin",n),v(this,"WINDOW_NAME","c8-wallet"),v(this,"WINDOW_WIDTH",475),v(this,"WINDOW_HEIGHT",762),v(this,"popup"),v(this,"sessionId",crypto.randomUUID()),v(this,"listening",!1),v(this,"walletReady",!1),v(this,"pending",new Map),v(this,"eventHandlers",new Set),v(this,"handshakeTimer"),v(this,"handshakeDeadline"),v(this,"closeWatcherTimer"),v(this,"pollingManager",f.getInstance()),v(this,"session",l.getInstance()),v(this,"initDeferred"),v(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.httpClient=new m,this.pollingManager.registerHandler(f.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(f.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(f.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){var e;this.session.hasStoredSession()&&null!=(e=this.session.getAccounts()[0])&&e.authToken&&this.pollingManager.add(f.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(!e.length)return!1;const t=this.session.getAccounts().map(t=>{const s=e.find(e=>e.party_id===t.partyId);return s?{...t,holdings:Object.entries(s.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}:t});return this.session.setAccounts(t),this.session.save(),!0}catch(e){e instanceof Error&&e.message.includes("401")&&this.destroy()}return!1}async getTransferStatusById(e,t){try{const s=await this.httpClient.getTransferStatus(e,t);let n;switch(s.status){case"success":n="confirmed";break;case"failed":n="failed";break;default:n="pending"}return s.status=n,s}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,e.partyId);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(f.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{if(await this.handleAccountUpdate()){this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const e=this.session.getExpireAt();return e&&this.scheduleDisconnect(e),!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=y()),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,c,h,l,u,p,g,f,m,w,v,I;const E=crypto.randomUUID(),T=y();this.pending.set(E,T);try{if("connect"===e){if(null!=(n=this.session.getAccounts()[0])&&n.authToken)return this.handleResponse({kind:"response",id:E,result:null}),T.promise;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:E,result:{connected:this.session.getConnected(),walletVersion:void 0}}),T.promise;if(s&&(null==(i=this.popup)||i.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:E,result:{instruments:e}}),T.promise}if("getActiveContracts"===e){const e=await this.httpClient.getActiveContracts(t);return this.handleResponse({kind:"response",id:E,result:e}),T.promise}if("getLedgerUpdates"===e){const e=await this.httpClient.getLedgerUpdates(t);return this.handleResponse({kind:"response",id:E,result:e}),T.promise}if("getContractsSetupState"===e){const e=t,s=await this.httpClient.getContractsSetupState(null==e?void 0:e.partyId),n={partyId:s.party_id,contracts:s.contracts.map(e=>({id:e.id,code:e.code,partyId:e.party_id,commandId:e.command_id,contractId:e.contract_id,status:e.status,submittedAt:e.submitted_at,completedAt:e.completed_at}))};return this.handleResponse({kind:"response",id:E,result:n}),T.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:E,result:{accounts:e}}),T.promise}if("checkTxStatusById"===e){const e=t,s=await this.getTransferStatusById(null==e?void 0:e.txId,null==e?void 0:e.partyId);if(s){const e={status:s.status,transfer:{senderPartyId:null!=(a=null==(r=s.transfer)?void 0:r.party_id)?a:"",receiverPartyId:null!=(d=null==(o=s.transfer)?void 0:o.party_id2)?d:"",amount:Number(null!=(h=null==(c=s.transfer)?void 0:c.amount)?h:"0"),networkFees:Number(null!=(u=null==(l=s.transfer)?void 0:l.network_fees)?u:"0"),instrumentId:null!=(g=null==(p=s.transfer)?void 0:p.instrument_id)?g:"",txId:null!=(m=null==(f=s.transfer)?void 0:f.command_id)?m:"",created_at:null!=(v=null==(w=s.transfer)?void 0:w.created_at)?v:"",memo:null==(I=s.transfer)?void 0:I.reason}};this.handleResponse({kind:"response",id:E,result:e})}else this.handleResponse({kind:"response",id:E,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return T.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:E,result:null}),T.promise;const y={kind:"request",id:E,method:e,params:t,sessionId:this.sessionId};this.post(y)}catch(e){this.pending.delete(E),T.reject(e)}return T.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){var t;if(e.origin!==this.origin)return;const s=e.data;if(s&&"object"==typeof s){if("event"===s.kind){for(const e of this.eventHandlers)"txInitiated"===s.event.type&&this.pollingManager.add(f.EVENT_TYPES.TRACK_TX_STATUS,{txId:s.event.txId,partyId:s.event.partyId,status:"initiated"}),e(s);return}if("internal_event"===s.kind)return void this.pollingManager.add(s.event.type,{wop:"wopwop"});if("auth-flow"===s.kind&&(this.session.setAccounts(s.accounts),this.session.setExpireAt(s.expireAt),this.session.setConnected(!(null==(t=s.accounts[0])||!t.authToken)),this.session.setInstruments(s.instruments),this.session.save(),this.scheduleDisconnect(s.expireAt)),"handshake-ack"===s.kind&&s.ok)return void this.handleHandshakeAck();"response"===s.kind&&this.handleResponse(s)}}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:s,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 E=Object.defineProperty,T=(e,t,s)=>((e,t,s)=>t in e?E(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function k(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class A{constructor(e,t,s,n){T(this,"appName",e),T(this,"appUrl",t),T(this,"targetOrigin",s),T(this,"targetWindow",n),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,"initDeferred"),this.onWindowMessage=this.onWindowMessage.bind(this),this.attachListener()}async init(){if(!this.walletReady){if(this.initDeferred||(this.initDeferred=k()),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=k();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=k();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:s,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 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 C(t){try{const s=new URL(t).hostname;return s===e||s.endsWith(`.${e}`)}catch{return!1}}class D{constructor(e){var s,n,i;b(this,"transport"),b(this,"listeners",{});const r=null!=(s=e.dappName)?s:document.title||"Unknown dApp",a=null!=(n=e.dappUrl)?n:location.origin,o=null!=(i=e.network)?i:"mainnet";let d;switch(o){case"local":d="http://localhost:8081";break;case"devnet":d=t;break;case"testmainnet":d="https://wallet.main.digik.cantor8.tech";break;case"mainnet":d="https://wallet.cantor8.tech";break;default:throw new Error("Unsupported network: "+o)}const c=function(){var e;if(window.parent===window)return;const t=null==(e=window.location.ancestorOrigins)?void 0:e[0];if(t&&C(t))return t;if(document.referrer)try{const e=new URL(document.referrer).origin;return C(e)?e:void 0}catch{return}}();this.transport=c?new A(r,a,c,window.parent):new I(r,a,d),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(e){return this.transport.request("getContractsSetupState",void 0===e?void 0:{partyId:e})}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 _={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},R="c8#provider_discovery";function O(e){const t={info:_,provider:e()};window.dispatchEvent(new CustomEvent(R,{detail:t}))}function U(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)}export{D as C8WalletProvider,m as HttpClient,n as LocalStorageHelper,O as announceC8Provider,U as onC8ProviderDiscovered};
@@ -1,11 +1,11 @@
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;
5
5
  constructor(opts: {
6
6
  dappName: string;
7
7
  dappUrl?: string;
8
- network?: "devnet" | "testmainnet" | "mainnet";
8
+ network?: "devnet" | "testmainnet" | "mainnet" | "local";
9
9
  });
10
10
  connect(): Promise<void>;
11
11
  disconnect(): Promise<void>;
@@ -13,7 +13,10 @@ export declare class C8WalletProvider {
13
13
  connected: boolean;
14
14
  walletVersion?: string;
15
15
  }>;
16
+ getContractsSetupState(partyId?: string): Promise<import("./types").PartyContractSetupResponse>;
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;
@@ -40,6 +43,7 @@ export declare class C8WalletProvider {
40
43
  private acknowledge;
41
44
  checkTxStatusById(input: {
42
45
  txId: string;
46
+ partyId?: string;
43
47
  }): Promise<import("./types").TransferStatusResponsePayload>;
44
48
  on<T extends C8EventType>(event: T, cb: Listener<C8EventByType<T>>): () => boolean;
45
49
  private emit;
package/dist/session.d.ts CHANGED
@@ -5,7 +5,6 @@ declare class Session {
5
5
  private appName;
6
6
  private accounts;
7
7
  private instruments;
8
- private authToken;
9
8
  private isConnected;
10
9
  private expireAt;
11
10
  private disconnectTimeoutId;
@@ -17,11 +16,10 @@ declare class Session {
17
16
  getInstruments(): InstrumentInfoPayload[];
18
17
  setAccounts(accounts: AccountInfoPayload[]): void;
19
18
  getAccounts(): AccountInfoPayload[];
20
- setBearerToken(token: string | null, expireAt: number | null): void;
19
+ setExpireAt(expireAt: number | null): void;
21
20
  getExpireAt(): number | null;
22
21
  setDisconnectTimeoutId(id: any): void;
23
22
  getDisconnectTimeoutId(): any;
24
- getBearerToken(): string | null;
25
23
  clear(): void;
26
24
  save(): void;
27
25
  setConnected(isConnected: boolean): void;
@@ -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";
@@ -1,8 +1,6 @@
1
1
  export declare const WALLET_ORIGIN_LOCAL = "http://localhost:8081";
2
2
  export declare const WALLET_BASE_DOMAIN = "cantor8.tech";
3
3
  export declare const WALLET_ORIGIN_DEVNET = "https://wallet.dev.digik.cantor8.tech";
4
- export declare const WALLET_API_DEVNET = "https://wallet-backend.dev.digik.cantor8.tech";
5
4
  export declare const WALLET_ORIGIN_MAINNET = "https://wallet.cantor8.tech";
6
- export declare const WALLET_API_MAINNET = "https://wallet-backend.main.digik.cantor8.tech";
7
5
  export declare const WALLET_ORIGIN_TEST_MAINNET = "https://wallet.main.digik.cantor8.tech";
8
6
  export declare const WALLET_EMBED_URL = "/embedded";
package/dist/types.d.ts CHANGED
@@ -17,6 +17,7 @@ export type C8Event = {
17
17
  } | {
18
18
  type: "txInitiated";
19
19
  txId?: string;
20
+ partyId?: string;
20
21
  meta?: Json;
21
22
  } | {
22
23
  type: "txChanged";
@@ -69,7 +70,6 @@ export type InboundMessage = {
69
70
  event: C8Event;
70
71
  } | {
71
72
  kind: "auth-flow";
72
- token: string;
73
73
  expireAt: number;
74
74
  accounts: AccountInfoPayload[];
75
75
  instruments: InstrumentInfoPayload[];
@@ -80,12 +80,17 @@ 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: {
89
+ partyId?: string;
90
+ } | undefined;
88
91
  getInstruments: undefined;
92
+ getActiveContracts: GetActiveContractsInput;
93
+ getLedgerUpdates: GetLedgerUpdatesInput;
89
94
  getAccounts: {
90
95
  instrumentId?: string;
91
96
  };
@@ -123,6 +128,7 @@ export interface WalletRequestPayloadMap {
123
128
  };
124
129
  checkTxStatusById: {
125
130
  txId: string;
131
+ partyId?: string;
126
132
  };
127
133
  createSwapOffer: {
128
134
  partyId: string;
@@ -182,6 +188,35 @@ export interface AppConfigPayload {
182
188
  update_url_android?: string | null;
183
189
  signups_guarded?: boolean;
184
190
  }
191
+ export interface ContractSetupItem {
192
+ id: number;
193
+ code: string;
194
+ partyId: string;
195
+ commandId: string;
196
+ contractId: string | null;
197
+ status: string;
198
+ submittedAt: string | null;
199
+ completedAt: string | null;
200
+ }
201
+ export interface PartyContractSetupResponse {
202
+ partyId: string;
203
+ contracts: ContractSetupItem[];
204
+ }
205
+ /** @deprecated getContractsSetupState now returns PartyContractSetupResponse. */
206
+ export interface RegisterStatusResponse {
207
+ isRegistered: boolean;
208
+ isConfirmed: boolean;
209
+ isPreapprovalSet: boolean;
210
+ isPreapprovalInProgress: boolean;
211
+ isAutoAcceptSet: boolean;
212
+ isAutoAcceptInProgress: boolean;
213
+ isUsdcBridgeSet: boolean;
214
+ isUsdcBridgeSetupInProgress: boolean;
215
+ isWithdrawalDelegationSet: boolean;
216
+ isWithdrawalDelegationInProgress: boolean;
217
+ isMergeDelegationSet: boolean;
218
+ isMergeDelegationInProgress: boolean;
219
+ }
185
220
  export interface AccountInfoHolding {
186
221
  instrumentId: string;
187
222
  balance: number;
@@ -190,9 +225,12 @@ export interface AccountInfoHolding {
190
225
  export interface ValidatorInfo {
191
226
  id: string;
192
227
  name: string;
228
+ scannerApiUrl?: string;
229
+ backendApiUrl?: string;
193
230
  }
194
231
  export interface AccountInfoPayload {
195
232
  accountName?: string;
233
+ authToken: string;
196
234
  partyId: string;
197
235
  publicKey: string;
198
236
  validator: ValidatorInfo;
@@ -227,6 +265,90 @@ export interface InstrumentInfoPayload {
227
265
  export interface InstrumentListPayload {
228
266
  instruments: InstrumentInfoPayload[];
229
267
  }
268
+ export interface GetLedgerUpdatesInput {
269
+ /** Defaults to the primary account; direct HTTP reads require that account. */
270
+ partyId?: string;
271
+ templateIds?: string[];
272
+ /** Scanner nextCursor, reused verbatim as an offset:nodeId string. */
273
+ cursor?: string;
274
+ eventType?: "created" | "exercised";
275
+ consuming?: boolean;
276
+ /** Integer from 1 to 1000; defaults to 500. */
277
+ limit?: number;
278
+ }
279
+ /** Scanner's page unchanged. Numeric payload fields use JavaScript precision. */
280
+ export interface LedgerUpdatesPayload {
281
+ nodes: LedgerNode[];
282
+ nextCursor?: string;
283
+ bounds?: {
284
+ floorOffset: number;
285
+ headOffset: number;
286
+ };
287
+ gap?: {
288
+ fromOffset: number;
289
+ toOffset: number;
290
+ reason?: string;
291
+ };
292
+ /** At Scanner's current fetch frontier, not the end of future ledger updates. */
293
+ complete: boolean;
294
+ }
295
+ export interface GetActiveContractsInput {
296
+ /** Defaults to the primary account; direct HTTP reads require that account. */
297
+ partyId?: string;
298
+ templateIds?: string[];
299
+ interfaceIds?: string[];
300
+ /** Nonnegative signed 64-bit decimal offset, kept as a string for precision. */
301
+ activeAtOffset?: string;
302
+ includeCreatedEventBlob?: boolean;
303
+ /** Positive integer; defaults to 10000. */
304
+ limit?: number;
305
+ /** Order by contract_id, including the first page; defaults to true. */
306
+ paginated?: boolean;
307
+ /** Resume after this contract_id, passed to Scanner unchanged. */
308
+ after?: string;
309
+ }
310
+ /** Scanner ledger node; optional witnesses distinguish unknown from empty. */
311
+ export interface LedgerNode {
312
+ offset: number;
313
+ nodeId: number;
314
+ updateId: string;
315
+ recordTime: string;
316
+ synchronizerId?: string;
317
+ commandId?: string;
318
+ workflowId?: string;
319
+ eventType: string;
320
+ consuming?: boolean;
321
+ acsDelta?: boolean;
322
+ lastDescendantNodeId?: number;
323
+ templateId?: string;
324
+ packageName?: string;
325
+ contractId?: string;
326
+ actingParties: string[];
327
+ witnessParties?: string[];
328
+ payload: Json;
329
+ }
330
+ /** Scanner contract row, retaining its original wire field names. */
331
+ export interface ScannerContract {
332
+ id: string;
333
+ contract_id: string;
334
+ template_id: string;
335
+ template_id_named: string;
336
+ interface_id?: string;
337
+ interface_id_wildcard?: string;
338
+ create_date: string;
339
+ create_event_id: string;
340
+ create_offset: number;
341
+ create_args: Json;
342
+ acting_parties: string[];
343
+ acting_dso: boolean;
344
+ acting_validator: boolean;
345
+ /** Base64-encoded created-event bytes, when requested. */
346
+ created_event_blob?: string;
347
+ archive_date: string;
348
+ archive_event_id?: string;
349
+ archive_offset?: number;
350
+ }
351
+ export type ActiveContractsPayload = ScannerContract[];
230
352
  export interface WalletResponsePayloadMap {
231
353
  connect: void;
232
354
  disconnect: void;
@@ -234,8 +356,11 @@ export interface WalletResponsePayloadMap {
234
356
  connected: boolean;
235
357
  walletVersion?: string;
236
358
  };
359
+ getContractsSetupState: PartyContractSetupResponse;
237
360
  getInstruments: InstrumentListPayload;
238
361
  getAccounts: AccountListPayload;
362
+ getActiveContracts: ActiveContractsPayload;
363
+ getLedgerUpdates: LedgerUpdatesPayload;
239
364
  send: SubmitTransferResultPayload;
240
365
  signMessage: string;
241
366
  signAndExecute: void;
@@ -1,8 +1,11 @@
1
- import { PartyHoldingsApiResponse, TransferTransactionApiResponse } from "./HttpClient.types";
1
+ import { ActiveContractsPayload, GetActiveContractsInput, GetLedgerUpdatesInput, LedgerUpdatesPayload } from "../types";
2
+ import { PartyHoldingsApiResponse, PartyContractSetupApiResponse, TransferTransactionApiResponse } from "./HttpClient.types";
2
3
  export declare class HttpClient {
3
- private readonly baseUrl;
4
- constructor(baseUrl: string);
5
4
  private request;
6
- getBalance(): Promise<PartyHoldingsApiResponse>;
7
- getTransferStatus(txId: string): Promise<TransferTransactionApiResponse>;
5
+ getActiveContracts(input?: GetActiveContractsInput): Promise<ActiveContractsPayload>;
6
+ private scannerRequest;
7
+ getLedgerUpdates(input?: GetLedgerUpdatesInput): Promise<LedgerUpdatesPayload>;
8
+ getBalance(): Promise<PartyHoldingsApiResponse[]>;
9
+ getTransferStatus(txId: string, partyId?: string): Promise<TransferTransactionApiResponse>;
10
+ getContractsSetupState(partyId?: string): Promise<PartyContractSetupApiResponse>;
8
11
  }
@@ -29,3 +29,30 @@ export interface PartyHoldingsApiResponse {
29
29
  party_id: string;
30
30
  holdings: Record<string, HoldingDetails>;
31
31
  }
32
+ export interface PartyContractSetupApiResponse {
33
+ party_id: string;
34
+ contracts: {
35
+ id: number;
36
+ code: string;
37
+ party_id: string;
38
+ command_id: string;
39
+ contract_id: string | null;
40
+ status: string;
41
+ submitted_at: string | null;
42
+ completed_at: string | null;
43
+ }[];
44
+ }
45
+ export interface RegisterStatusApiResponse {
46
+ is_registered: boolean;
47
+ is_confirmed: boolean;
48
+ is_preapproval_set: boolean;
49
+ is_preapproval_in_progress: boolean;
50
+ is_auto_accept_set: boolean;
51
+ is_auto_accept_in_progress: boolean;
52
+ is_usdc_bridge_set: boolean;
53
+ is_usdc_bridge_setup_in_progress: boolean;
54
+ is_withdrawal_delegation_set: boolean;
55
+ is_withdrawal_delegation_in_progress: boolean;
56
+ is_merge_delegation_set: boolean;
57
+ is_merge_delegation_in_progress: boolean;
58
+ }
@@ -0,0 +1 @@
1
+ export declare const SDK_VERSION: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@cantor8/wallet-connect-sdk",
3
- "version": "0.5.1",
3
+ "version": "0.7.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
- }