@cantor8/wallet-connect-sdk 0.3.0-alpha.2 → 0.3.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 +108 -49
- package/dist/index.cjs +1 -1
- package/dist/index.esm.js +1 -1
- package/dist/provider.d.ts +1 -1
- package/dist/types.d.ts +1 -1
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -1,90 +1,149 @@
|
|
|
1
|
-
|
|
2
1
|
# C8 Wallet Connect SDK
|
|
3
2
|
|
|
4
|
-
Lightweight SDK for dApp developers to integrate the C8 Wallet via a popup window and postMessage communication.
|
|
3
|
+
Lightweight SDK for dApp developers to integrate the C8 Wallet via a popup window and `postMessage` communication.
|
|
4
|
+
|
|
5
|
+
## Quick Start
|
|
6
|
+
|
|
7
|
+
### Installation
|
|
8
|
+
```shell
|
|
9
|
+
npm i @cantor8/wallet-connect-sdk
|
|
10
|
+
```
|
|
5
11
|
|
|
6
|
-
|
|
12
|
+
Import the provider into your dApp:
|
|
7
13
|
|
|
14
|
+
```ts
|
|
15
|
+
import { C8WalletProvider } from "./provider";
|
|
16
|
+
```
|
|
8
17
|
|
|
9
18
|
## Configuration
|
|
10
19
|
|
|
11
|
-
|
|
20
|
+
Create a new provider instance:
|
|
12
21
|
|
|
13
|
-
```
|
|
22
|
+
```ts
|
|
14
23
|
const c8 = new C8WalletProvider({
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
24
|
+
dappUrl: window.location.href,
|
|
25
|
+
dappName: "Cantor8 Wallet Connect SDK Demo",
|
|
26
|
+
network: "devnet",
|
|
18
27
|
});
|
|
19
28
|
```
|
|
20
29
|
|
|
21
|
-
|
|
30
|
+
## Events
|
|
22
31
|
|
|
23
|
-
|
|
24
|
-
c8.on('connected', (e) => console.log('Connected', e));
|
|
25
|
-
c8.on('disconnected', (e) => console.log('Disconnected', e));
|
|
26
|
-
c8.on('accountChanged', (e) => console.log('account's balance changed', e));
|
|
27
|
-
c8.on('txInitiated', (e) => console.log('TX initiated', e));
|
|
28
|
-
c8.on('txChanged', (e) => console.log('TX changed', e));
|
|
29
|
-
```
|
|
30
|
-
|
|
31
|
-
Basic usage
|
|
32
|
+
You can subscribe to wallet events using `c8.on()`:
|
|
32
33
|
|
|
34
|
+
```ts
|
|
35
|
+
c8.on("connected", (e) => console.log("Connected", e));
|
|
36
|
+
c8.on("disconnected", (e) => console.log("Disconnected", e));
|
|
37
|
+
c8.on("accountChanged", (e) => console.log("Account's balance changed", e));
|
|
38
|
+
c8.on("txInitiated", (e) => console.log("TX initiated", e));
|
|
39
|
+
c8.on("txChanged", (e) => console.log("TX changed", e));
|
|
33
40
|
```
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
41
|
+
|
|
42
|
+
## Basic Usage
|
|
43
|
+
|
|
44
|
+
```ts
|
|
45
|
+
const c8 = new C8WalletProvider({
|
|
46
|
+
dappUrl: window.location.href,
|
|
47
|
+
dappName: "Cantor8 Wallet Connect SDK Demo",
|
|
48
|
+
network: "devnet",
|
|
38
49
|
});
|
|
39
50
|
|
|
40
51
|
await c8.connect();
|
|
41
52
|
|
|
42
53
|
// Instruments list type: InstrumentListPayload
|
|
43
54
|
const instruments = await c8.getInstruments();
|
|
44
|
-
console.log(
|
|
55
|
+
console.log("Instruments", instruments);
|
|
45
56
|
|
|
46
57
|
const firstInstrumentId = instruments.instruments[0]?.instrumentId;
|
|
47
58
|
|
|
48
59
|
// Accounts list type: AccountListPayload
|
|
49
|
-
const accounts = await
|
|
50
|
-
console.log(
|
|
60
|
+
const accounts = await c8.getAccounts(firstInstrumentId);
|
|
61
|
+
console.log("Accounts", accounts);
|
|
51
62
|
|
|
52
63
|
const senderPartyId = accounts.accounts[0]?.partyId;
|
|
53
|
-
|
|
64
|
+
|
|
65
|
+
const senderHoldingInstrumentId =
|
|
66
|
+
accounts.accounts[0]?.holdings[0]?.instrumentId || firstInstrumentId;
|
|
54
67
|
|
|
55
68
|
// Submit a transfer
|
|
56
69
|
// SubmitTransferResultPayload
|
|
57
70
|
const res = await c8.send({
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
71
|
+
senderPartyId,
|
|
72
|
+
instrumentId: senderHoldingInstrumentId,
|
|
73
|
+
amount: 1.23,
|
|
74
|
+
receiverPartyId: "Party::Receiver",
|
|
62
75
|
});
|
|
63
|
-
|
|
76
|
+
|
|
77
|
+
console.log("Send result", res); // { txId }
|
|
64
78
|
```
|
|
79
|
+
|
|
65
80
|
## API Reference
|
|
66
81
|
|
|
67
|
-
|
|
82
|
+
### Public API: `C8WalletProvider`
|
|
83
|
+
|
|
84
|
+
| Method | Parameters | Return Type |
|
|
85
|
+
| --------------------- | ------------------------------------------ | --------------------------------------------------------- |
|
|
86
|
+
| `connect()` | None | `Promise<void>` |
|
|
87
|
+
| `disconnect()` | None | `Promise<void>` |
|
|
88
|
+
| `status()` | None | `Promise<{ connected: boolean; walletVersion?: string }>` |
|
|
89
|
+
| `getInstruments()` | None | `Promise<InstrumentListPayload>` |
|
|
90
|
+
| `getAccounts()` | `instrumentId?: string` | `Promise<AccountListPayload>` |
|
|
91
|
+
| `send()` | `input: SendInput` | `Promise<SubmitTransferResultPayload>` |
|
|
92
|
+
| `signAndExecute()` | `input: SignAndExecuteInput` | `Promise<void>` |
|
|
93
|
+
| `checkTxStatusById()` | `input: { txId: string }` | `Promise<TransferStatusResponsePayload>` |
|
|
94
|
+
| `on()` | `event: T, cb: Listener<C8EventByType<T>>` | `() => boolean` |
|
|
95
|
+
|
|
96
|
+
### `send()` Input
|
|
97
|
+
|
|
98
|
+
```ts
|
|
99
|
+
{
|
|
100
|
+
senderPartyId: string;
|
|
101
|
+
instrumentId: string;
|
|
102
|
+
amount: number;
|
|
103
|
+
receiverPartyId: string;
|
|
104
|
+
memo?: string;
|
|
105
|
+
metadata?: Record<string, string>;
|
|
106
|
+
}
|
|
107
|
+
```
|
|
108
|
+
|
|
109
|
+
### `signAndExecute()` Input
|
|
110
|
+
|
|
111
|
+
```ts
|
|
112
|
+
{
|
|
113
|
+
note: string;
|
|
114
|
+
partyId: string;
|
|
115
|
+
commandId: string;
|
|
116
|
+
commandsJson: string;
|
|
117
|
+
disclosedContracts: string;
|
|
118
|
+
}
|
|
119
|
+
```
|
|
68
120
|
|
|
69
|
-
|
|
70
|
-
| :-------- |
|
|
71
|
-
| `connect(): Promise<void>` |
|
|
72
|
-
| `disconnect(): Promise<void>` |
|
|
73
|
-
| `status(): Promise<{connected: boolean, walletVersion?: string}>` |
|
|
74
|
-
| `getInstruments(): Promise<InstrumentListPayload>` |
|
|
75
|
-
| `getAccounts(instrumentId?: string): Promise<AccountListPayload>` |
|
|
76
|
-
| `send(input: {senderPartyId: string, instrumentId: string, amount: number, receiverPartyId: string, memo?: string, metadata?: Record<string, string>}): Promise<SubmitTransferResultPayload>` |
|
|
77
|
-
| `checkTxStatusById(input: {partyId: string, txId: string}): Promise<TransferStatusResponsePayload>` |
|
|
121
|
+
## Events Reference
|
|
78
122
|
|
|
79
|
-
|
|
123
|
+
Use `c8.on(eventType, callback)` to listen for changes emitted by the wallet.
|
|
80
124
|
|
|
81
|
-
|
|
|
82
|
-
|
|
|
83
|
-
| `connected` |
|
|
84
|
-
| `disconnected` |
|
|
85
|
-
| `
|
|
86
|
-
| `
|
|
87
|
-
| `
|
|
125
|
+
| Event Type | Payload Properties | Description |
|
|
126
|
+
| ------------------- | --------------------------------------------------------------------------------------- | --------------------------------------------------------------------------- |
|
|
127
|
+
| `connected` | `meta?: Json` | Fired when the wallet successfully connects. |
|
|
128
|
+
| `disconnected` | `reason?: string`, `meta?: Json` | Fired when the session disconnects. |
|
|
129
|
+
| `txInitiated` | `txId?: string`, `meta?: Json` | Fired when a transaction request is initiated. |
|
|
130
|
+
| `txChanged` | `txId: string`, `status: "pending" \| "confirmed" \| "failed" \| string`, `meta?: Json` | Fired when a transaction's completion status updates. |
|
|
131
|
+
| `accountChanged` | `accounts: AccountInfoPayload[]`, `meta?: Json` | Fired when internal account asset holdings scale or modify. |
|
|
132
|
+
| `themeChanged` | `theme: "dark" \| "light"`, `meta?: Json` | Fired when the wallet interface changes its UI display theme. |
|
|
133
|
+
| `operationCanceled` | `reason: string`, `meta?: Json` | Fired when an action or modal interface is explicitly rejected by the user. |
|
|
88
134
|
|
|
135
|
+
## Unsubscribing from Events
|
|
136
|
+
|
|
137
|
+
The `on()` method returns an unsubscribe function:
|
|
138
|
+
|
|
139
|
+
```ts
|
|
140
|
+
const unsubscribe = c8.on("connected", (event) => {
|
|
141
|
+
console.log("Connected", event);
|
|
142
|
+
});
|
|
143
|
+
|
|
144
|
+
unsubscribe();
|
|
145
|
+
```
|
|
89
146
|
|
|
147
|
+
## License
|
|
90
148
|
|
|
149
|
+
MIT
|
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";const e="https://wallet.dev.digik.cantor8.tech",t="https://wallet-backend.dev.digik.cantor8.tech";class s{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 n={TestCoin1:"TestCoin1",Amulet:"Canton Coin",CBTC:"CBTC",USDCx:"USDCx",CETH:"CETH"},i=e=>{var t;return"Amulet"===e?"Canton Coin":null!=(t=n[null!=e?e:""])?t:e},r={TestCoin1:"TestCoin1",Amulet:"CC",CBTC:"CBTC",USDCx:"USDCx"},a=e=>{var t;return"Amulet"===e?"CC":null!=(t=r[null!=e?e:""])?t:e};var o=Object.defineProperty,h=(e,t,s)=>((e,t,s)=>t in e?o(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const d=class e{constructor(){h(this,"appName"),h(this,"accounts",[]),h(this,"instruments",[]),h(this,"partyIds",[]),h(this,"authToken",null),h(this,"isConnected",!1),h(this,"expireAt",null),h(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.partyIds=e.map(e=>e.partyId),this.instruments=e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:i(e.instrumentId),symbol:a(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.partyIds=[],this.isConnected=!1,this.expireAt=null,this.disconnectTimeoutId&&(clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=null),s.removeItem(e.SESSION_KEY)}save(){s.setItem(e.SESSION_KEY,{authToken:this.authToken,partyIds:this.partyIds,expireAt:this.expireAt})}setConnected(e){this.isConnected=e}getConnected(){return this.isConnected}hasStoredSession(){return!!s.getItem(e.SESSION_KEY)}load(){const t=s.getItem(e.SESSION_KEY);t&&(this.authToken=t.authToken,this.partyIds=t.partyIds||[],this.expireAt=t.expireAt||null)}};h(d,"instance"),h(d,"SESSION_KEY","c8-session");let c=d;var l=Object.defineProperty,u=(e,t,s)=>((e,t,s)=>t in e?l(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const p=class e{constructor(e=5e3){this.pollingInterval=e,u(this,"events",new Map),u(this,"intervals",new Map),u(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);s.setItem(e.STORAGE_KEY,t)}restore(){const t=s.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(),s.removeItem(e.STORAGE_KEY)}getEvents(){return Array.from(this.events.values()).map(e=>e.event)}};u(p,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),u(p,"type"),u(p,"instance"),u(p,"STORAGE_KEY","c8-polling-events"),u(p,"POLLING_TIMEOUT",3e5);let m=p;var g=Object.defineProperty;class v{constructor(e){((e,t,s)=>{((e,t,s)=>{t in e?g(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=c.getInstance().getBearerToken(),n=c.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 T=Object.defineProperty,I=(e,t,s)=>((e,t,s)=>t in e?T(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function f(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class w{constructor(s,n,i=e){let r;switch(this.appName=s,this.appUrl=n,this.origin=i,I(this,"WINDOW_NAME","c8-wallet"),I(this,"WINDOW_WIDTH",475),I(this,"WINDOW_HEIGHT",762),I(this,"popup"),I(this,"sessionId",crypto.randomUUID()),I(this,"listening",!1),I(this,"walletReady",!1),I(this,"pending",new Map),I(this,"eventHandlers",new Set),I(this,"handshakeTimer"),I(this,"handshakeDeadline"),I(this,"closeWatcherTimer"),I(this,"pollingManager",m.getInstance()),I(this,"session",c.getInstance()),I(this,"initDeferred"),I(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 e:r=t;break;case"https://wallet.cantor8.tech":case"https://wallet.main.digik.cantor8.tech":r="https://wallet-backend.main.cantor8.tech";break;default:r=t}this.httpClient=new v(r),this.pollingManager.registerHandler(m.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(m.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(m.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){this.session.hasStoredSession()&&this.pollingManager.add(m.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=[{partyId:e.party_id,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(t),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(m.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=[{partyId:e.party_id,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(t),this.session.save(),this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const s=this.session.getExpireAt();return s&&this.scheduleDisconnect(s),!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=f()),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,m,g,v,T,I;const w=crypto.randomUUID(),E=f();this.pending.set(w,E);try{if("connect"===e){if(this.session.getBearerToken())return this.handleResponse({kind:"response",id:w,result:null}),E.promise;this.session.getBearerToken()||(this.walletReady=!1),await this.init()}if("send"===e&&(this.walletReady=!1,await this.init("confirmTransaction")),"signAndExecute"===e&&(this.walletReady=!1,await this.init("signAndExecute")),"status"===e)return this.handleResponse({kind:"response",id:w,result:{connected:this.session.getConnected(),walletVersion:void 0}}),E.promise;if(s&&(null==(n=this.popup)||n.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:w,result:{instruments:e}}),E.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:w,result:{accounts:e}}),E.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!=(g=null==(m=s.transfer)?void 0:m.command_id)?g:"",created_at:null!=(T=null==(v=s.transfer)?void 0:v.created_at)?T:"",memo:null==(I=s.transfer)?void 0:I.reason}};this.handleResponse({kind:"response",id:w,result:e})}else this.handleResponse({kind:"response",id:w,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return E.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:w,result:null}),E.promise;const f={kind:"request",id:w,method:e,params:t,sessionId:this.sessionId};this.post(f)}catch(e){this.pending.delete(w),E.reject(e)}return E.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(m.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 E=Object.defineProperty,y=(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);const k={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},S="c8#provider_discovery";exports.C8WalletProvider=class{constructor(t){var s,n,i;y(this,"transport"),y(this,"listeners",{});const r=null!=(s=t.dappName)?s:document.title||"Unknown dApp",a=null!=(n=t.dappUrl)?n:location.origin,o=null!=(i=t.network)?i:"mainnet";let h;if("devnet"!==o)throw new Error("Only devnet network is supported right now");if("devnet"!==o)throw new Error("Unsupported network: "+o);h=e,this.transport=new w(r,a,h),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)}signAndExecute(e){return this.transport.request("signAndExecute",e,!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=v,exports.LocalStorageHelper=s,exports.announceC8Provider=function(e){const t={info:k,provider:e()};window.dispatchEvent(new CustomEvent(S,{detail:t}))},exports.onC8ProviderDiscovered=function(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(S,t),()=>window.removeEventListener(S,t)};
|
|
1
|
+
"use strict";const e="https://wallet.dev.digik.cantor8.tech",t="https://wallet-backend.dev.digik.cantor8.tech",s="https://wallet.cantor8.tech";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 h=Object.defineProperty,d=(e,t,s)=>((e,t,s)=>t in e?h(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const c=class e{constructor(){d(this,"appName"),d(this,"accounts",[]),d(this,"instruments",[]),d(this,"partyIds",[]),d(this,"authToken",null),d(this,"isConnected",!1),d(this,"expireAt",null),d(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.partyIds=e.map(e=>e.partyId),this.instruments=e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:r(e.instrumentId),symbol:o(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.partyIds=[],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,{authToken:this.authToken,partyIds:this.partyIds,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.authToken=t.authToken,this.partyIds=t.partyIds||[],this.expireAt=t.expireAt||null)}};d(c,"instance"),d(c,"SESSION_KEY","c8-session");let l=c;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 m=class e{constructor(e=5e3){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(m,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),p(m,"type"),p(m,"instance"),p(m,"STORAGE_KEY","c8-polling-events"),p(m,"POLLING_TIMEOUT",3e5);let g=m;var T=Object.defineProperty;class v{constructor(e){((e,t,s)=>{((e,t,s)=>{t in e?T(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=l.getInstance().getBearerToken(),n=l.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 I=Object.defineProperty,f=(e,t,s)=>((e,t,s)=>t in e?I(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function w(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class E{constructor(n,i,r=e){let a;switch(this.appName=n,this.appUrl=i,this.origin=r,f(this,"WINDOW_NAME","c8-wallet"),f(this,"WINDOW_WIDTH",475),f(this,"WINDOW_HEIGHT",762),f(this,"popup"),f(this,"sessionId",crypto.randomUUID()),f(this,"listening",!1),f(this,"walletReady",!1),f(this,"pending",new Map),f(this,"eventHandlers",new Set),f(this,"handshakeTimer"),f(this,"handshakeDeadline"),f(this,"closeWatcherTimer"),f(this,"pollingManager",g.getInstance()),f(this,"session",l.getInstance()),f(this,"initDeferred"),f(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 e:a=t;break;case s:case"https://wallet.main.digik.cantor8.tech":a="https://wallet-backend.main.cantor8.tech";break;default:a=t}this.httpClient=new v(a),this.pollingManager.registerHandler(g.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(g.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(g.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){this.session.hasStoredSession()&&this.pollingManager.add(g.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=[{partyId:e.party_id,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(t),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(g.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=[{partyId:e.party_id,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(t),this.session.save(),this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const s=this.session.getExpireAt();return s&&this.scheduleDisconnect(s),!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=w()),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,m,g,T,v,I;const f=crypto.randomUUID(),E=w();this.pending.set(f,E);try{if("connect"===e){if(this.session.getBearerToken())return this.handleResponse({kind:"response",id:f,result:null}),E.promise;this.session.getBearerToken()||(this.walletReady=!1),await this.init()}if("send"===e&&(this.walletReady=!1,await this.init("confirmTransaction")),"signAndExecute"===e&&(this.walletReady=!1,await this.init("signAndExecute")),"status"===e)return this.handleResponse({kind:"response",id:f,result:{connected:this.session.getConnected(),walletVersion:void 0}}),E.promise;if(s&&(null==(n=this.popup)||n.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:f,result:{instruments:e}}),E.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:f,result:{accounts:e}}),E.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!=(g=null==(m=s.transfer)?void 0:m.command_id)?g:"",created_at:null!=(v=null==(T=s.transfer)?void 0:T.created_at)?v:"",memo:null==(I=s.transfer)?void 0:I.reason}};this.handleResponse({kind:"response",id:f,result:e})}else this.handleResponse({kind:"response",id:f,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return E.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:f,result:null}),E.promise;const w={kind:"request",id:f,method:e,params:t,sessionId:this.sessionId};this.post(w)}catch(e){this.pending.delete(f),E.reject(e)}return E.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(g.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 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);const S={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},A="c8#provider_discovery";exports.C8WalletProvider=class{constructor(t){var n,i,r;k(this,"transport"),k(this,"listeners",{});const a=null!=(n=t.dappName)?n:document.title||"Unknown dApp",o=null!=(i=t.dappUrl)?i:location.origin,h=null!=(r=t.network)?r:"mainnet";let d;switch(h){case"devnet":d=e;break;case"mainnet":d=s;break;default:throw new Error("Unsupported network: "+h)}this.transport=new E(a,o,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")}getInstruments(){return this.transport.request("getInstruments")}getAccounts(e){return this.transport.request("getAccounts",{instrumentId:e})}send(e){return this.transport.request("send",e,!0)}signAndExecute(e){return this.transport.request("signAndExecute",e,!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=v,exports.LocalStorageHelper=n,exports.announceC8Provider=function(e){const t={info:S,provider:e()};window.dispatchEvent(new CustomEvent(A,{detail:t}))},exports.onC8ProviderDiscovered=function(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(A,t),()=>window.removeEventListener(A,t)};
|
package/dist/index.esm.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
const e="https://wallet.dev.digik.cantor8.tech",t="https://wallet-backend.dev.digik.cantor8.tech";class s{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 n={TestCoin1:"TestCoin1",Amulet:"Canton Coin",CBTC:"CBTC",USDCx:"USDCx",CETH:"CETH"},i=e=>{var t;return"Amulet"===e?"Canton Coin":null!=(t=n[null!=e?e:""])?t:e},r={TestCoin1:"TestCoin1",Amulet:"CC",CBTC:"CBTC",USDCx:"USDCx"},a=e=>{var t;return"Amulet"===e?"CC":null!=(t=r[null!=e?e:""])?t:e};var o=Object.defineProperty,h=(e,t,s)=>((e,t,s)=>t in e?o(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const d=class e{constructor(){h(this,"appName"),h(this,"accounts",[]),h(this,"instruments",[]),h(this,"partyIds",[]),h(this,"authToken",null),h(this,"isConnected",!1),h(this,"expireAt",null),h(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.partyIds=e.map(e=>e.partyId),this.instruments=e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:i(e.instrumentId),symbol:a(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.partyIds=[],this.isConnected=!1,this.expireAt=null,this.disconnectTimeoutId&&(clearTimeout(this.disconnectTimeoutId),this.disconnectTimeoutId=null),s.removeItem(e.SESSION_KEY)}save(){s.setItem(e.SESSION_KEY,{authToken:this.authToken,partyIds:this.partyIds,expireAt:this.expireAt})}setConnected(e){this.isConnected=e}getConnected(){return this.isConnected}hasStoredSession(){return!!s.getItem(e.SESSION_KEY)}load(){const t=s.getItem(e.SESSION_KEY);t&&(this.authToken=t.authToken,this.partyIds=t.partyIds||[],this.expireAt=t.expireAt||null)}};h(d,"instance"),h(d,"SESSION_KEY","c8-session");let c=d;var l=Object.defineProperty,u=(e,t,s)=>((e,t,s)=>t in e?l(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const p=class e{constructor(e=5e3){this.pollingInterval=e,u(this,"events",new Map),u(this,"intervals",new Map),u(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);s.setItem(e.STORAGE_KEY,t)}restore(){const t=s.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(),s.removeItem(e.STORAGE_KEY)}getEvents(){return Array.from(this.events.values()).map(e=>e.event)}};u(p,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),u(p,"type"),u(p,"instance"),u(p,"STORAGE_KEY","c8-polling-events"),u(p,"POLLING_TIMEOUT",3e5);let m=p;var g=Object.defineProperty;class v{constructor(e){((e,t,s)=>{((e,t,s)=>{t in e?g(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=c.getInstance().getBearerToken(),n=c.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 T=Object.defineProperty,I=(e,t,s)=>((e,t,s)=>t in e?T(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function f(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class w{constructor(s,n,i=e){let r;switch(this.appName=s,this.appUrl=n,this.origin=i,I(this,"WINDOW_NAME","c8-wallet"),I(this,"WINDOW_WIDTH",475),I(this,"WINDOW_HEIGHT",762),I(this,"popup"),I(this,"sessionId",crypto.randomUUID()),I(this,"listening",!1),I(this,"walletReady",!1),I(this,"pending",new Map),I(this,"eventHandlers",new Set),I(this,"handshakeTimer"),I(this,"handshakeDeadline"),I(this,"closeWatcherTimer"),I(this,"pollingManager",m.getInstance()),I(this,"session",c.getInstance()),I(this,"initDeferred"),I(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 e:r=t;break;case"https://wallet.cantor8.tech":case"https://wallet.main.digik.cantor8.tech":r="https://wallet-backend.main.cantor8.tech";break;default:r=t}this.httpClient=new v(r),this.pollingManager.registerHandler(m.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(m.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(m.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){this.session.hasStoredSession()&&this.pollingManager.add(m.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=[{partyId:e.party_id,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(t),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(m.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=[{partyId:e.party_id,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(t),this.session.save(),this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const s=this.session.getExpireAt();return s&&this.scheduleDisconnect(s),!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=f()),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,m,g,v,T,I;const w=crypto.randomUUID(),E=f();this.pending.set(w,E);try{if("connect"===e){if(this.session.getBearerToken())return this.handleResponse({kind:"response",id:w,result:null}),E.promise;this.session.getBearerToken()||(this.walletReady=!1),await this.init()}if("send"===e&&(this.walletReady=!1,await this.init("confirmTransaction")),"signAndExecute"===e&&(this.walletReady=!1,await this.init("signAndExecute")),"status"===e)return this.handleResponse({kind:"response",id:w,result:{connected:this.session.getConnected(),walletVersion:void 0}}),E.promise;if(s&&(null==(n=this.popup)||n.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:w,result:{instruments:e}}),E.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:w,result:{accounts:e}}),E.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!=(g=null==(m=s.transfer)?void 0:m.command_id)?g:"",created_at:null!=(T=null==(v=s.transfer)?void 0:v.created_at)?T:"",memo:null==(I=s.transfer)?void 0:I.reason}};this.handleResponse({kind:"response",id:w,result:e})}else this.handleResponse({kind:"response",id:w,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return E.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:w,result:null}),E.promise;const f={kind:"request",id:w,method:e,params:t,sessionId:this.sessionId};this.post(f)}catch(e){this.pending.delete(w),E.reject(e)}return E.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(m.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 E=Object.defineProperty,y=(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);class k{constructor(t){var s,n,i;y(this,"transport"),y(this,"listeners",{});const r=null!=(s=t.dappName)?s:document.title||"Unknown dApp",a=null!=(n=t.dappUrl)?n:location.origin,o=null!=(i=t.network)?i:"mainnet";let h;if("devnet"!==o)throw new Error("Only devnet network is supported right now");if("devnet"!==o)throw new Error("Unsupported network: "+o);h=e,this.transport=new w(r,a,h),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)}signAndExecute(e){return this.transport.request("signAndExecute",e,!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 S={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},A="c8#provider_discovery";function b(e){const t={info:S,provider:e()};window.dispatchEvent(new CustomEvent(A,{detail:t}))}function C(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(A,t),()=>window.removeEventListener(A,t)}export{k as C8WalletProvider,v as HttpClient,s as LocalStorageHelper,b as announceC8Provider,C as onC8ProviderDiscovered};
|
|
1
|
+
const e="https://wallet.dev.digik.cantor8.tech",t="https://wallet-backend.dev.digik.cantor8.tech",s="https://wallet.cantor8.tech";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 h=Object.defineProperty,d=(e,t,s)=>((e,t,s)=>t in e?h(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);const c=class e{constructor(){d(this,"appName"),d(this,"accounts",[]),d(this,"instruments",[]),d(this,"partyIds",[]),d(this,"authToken",null),d(this,"isConnected",!1),d(this,"expireAt",null),d(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.partyIds=e.map(e=>e.partyId),this.instruments=e.flatMap(e=>e.holdings.map(e=>({instrumentId:e.instrumentId,name:r(e.instrumentId),symbol:o(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.partyIds=[],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,{authToken:this.authToken,partyIds:this.partyIds,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.authToken=t.authToken,this.partyIds=t.partyIds||[],this.expireAt=t.expireAt||null)}};d(c,"instance"),d(c,"SESSION_KEY","c8-session");let l=c;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 m=class e{constructor(e=5e3){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(m,"EVENT_TYPES",{RESTORE_SESSION:"RESTORE_SESSION",TRACK_TX_STATUS:"TRACK_TX_STATUS",UPDATE_ACCOUNT:"UPDATE_ACCOUNT"}),p(m,"type"),p(m,"instance"),p(m,"STORAGE_KEY","c8-polling-events"),p(m,"POLLING_TIMEOUT",3e5);let g=m;var T=Object.defineProperty;class v{constructor(e){((e,t,s)=>{((e,t,s)=>{t in e?T(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=l.getInstance().getBearerToken(),n=l.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 I=Object.defineProperty,f=(e,t,s)=>((e,t,s)=>t in e?I(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s)(e,"symbol"!=typeof t?t+"":t,s);function w(){let e,t;return{promise:new Promise((s,n)=>{e=s,t=n}),resolve:e,reject:t}}class E{constructor(n,i,r=e){let a;switch(this.appName=n,this.appUrl=i,this.origin=r,f(this,"WINDOW_NAME","c8-wallet"),f(this,"WINDOW_WIDTH",475),f(this,"WINDOW_HEIGHT",762),f(this,"popup"),f(this,"sessionId",crypto.randomUUID()),f(this,"listening",!1),f(this,"walletReady",!1),f(this,"pending",new Map),f(this,"eventHandlers",new Set),f(this,"handshakeTimer"),f(this,"handshakeDeadline"),f(this,"closeWatcherTimer"),f(this,"pollingManager",g.getInstance()),f(this,"session",l.getInstance()),f(this,"initDeferred"),f(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 e:a=t;break;case s:case"https://wallet.main.digik.cantor8.tech":a="https://wallet-backend.main.cantor8.tech";break;default:a=t}this.httpClient=new v(a),this.pollingManager.registerHandler(g.EVENT_TYPES.RESTORE_SESSION,this.handleRestoreSession),this.pollingManager.registerHandler(g.EVENT_TYPES.TRACK_TX_STATUS,this.handleTrackTxStatus),this.pollingManager.registerHandler(g.EVENT_TYPES.UPDATE_ACCOUNT,this.handleAccountUpdate),this.checkRestoreSession()}checkRestoreSession(){this.session.hasStoredSession()&&this.pollingManager.add(g.EVENT_TYPES.RESTORE_SESSION,{sessionId:this.sessionId})}async handleAccountUpdate(e){try{const e=await this.httpClient.getBalance();if(e&&e.holdings){const t=[{partyId:e.party_id,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(t),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(g.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=[{partyId:e.party_id,holdings:Object.entries(e.holdings).map(([e,t])=>({instrumentId:e,balance:Number(t.balance),balanceUsd:Number(t.balance_usd)}))}];this.session.setAccounts(t),this.session.save(),this.session.setConnected(!0),this.emitSyntheticEvent({type:"connected"});const s=this.session.getExpireAt();return s&&this.scheduleDisconnect(s),!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=w()),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,m,g,T,v,I;const f=crypto.randomUUID(),E=w();this.pending.set(f,E);try{if("connect"===e){if(this.session.getBearerToken())return this.handleResponse({kind:"response",id:f,result:null}),E.promise;this.session.getBearerToken()||(this.walletReady=!1),await this.init()}if("send"===e&&(this.walletReady=!1,await this.init("confirmTransaction")),"signAndExecute"===e&&(this.walletReady=!1,await this.init("signAndExecute")),"status"===e)return this.handleResponse({kind:"response",id:f,result:{connected:this.session.getConnected(),walletVersion:void 0}}),E.promise;if(s&&(null==(n=this.popup)||n.focus()),"getInstruments"===e){const e=this.session.getInstruments();return this.handleResponse({kind:"response",id:f,result:{instruments:e}}),E.promise}if("getAccounts"===e){await this.handleAccountUpdate();const e=this.session.getAccounts();return this.handleResponse({kind:"response",id:f,result:{accounts:e}}),E.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!=(g=null==(m=s.transfer)?void 0:m.command_id)?g:"",created_at:null!=(v=null==(T=s.transfer)?void 0:T.created_at)?v:"",memo:null==(I=s.transfer)?void 0:I.reason}};this.handleResponse({kind:"response",id:f,result:e})}else this.handleResponse({kind:"response",id:f,error:{code:"FAILED_TO_FETCH_TRANSFER_STATUS",message:"Failed to fetch transfer status"}});return E.promise}if("disconnect"===e)return this.handleResponse({kind:"response",id:f,result:null}),E.promise;const w={kind:"request",id:f,method:e,params:t,sessionId:this.sessionId};this.post(w)}catch(e){this.pending.delete(f),E.reject(e)}return E.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(g.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 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);class S{constructor(t){var n,i,r;k(this,"transport"),k(this,"listeners",{});const a=null!=(n=t.dappName)?n:document.title||"Unknown dApp",o=null!=(i=t.dappUrl)?i:location.origin,h=null!=(r=t.network)?r:"mainnet";let d;switch(h){case"devnet":d=e;break;case"mainnet":d=s;break;default:throw new Error("Unsupported network: "+h)}this.transport=new E(a,o,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")}getInstruments(){return this.transport.request("getInstruments")}getAccounts(e){return this.transport.request("getAccounts",{instrumentId:e})}send(e){return this.transport.request("send",e,!0)}signAndExecute(e){return this.transport.request("signAndExecute",e,!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 A={uuid:"c8-wallet-connect",name:"C8 Wallet",icon:"",rdns:"tech.cantor8.wallet"},b="c8#provider_discovery";function C(e){const t={info:A,provider:e()};window.dispatchEvent(new CustomEvent(b,{detail:t}))}function _(e){const t=t=>{const s=t;s.detail&&e(s.detail.info,s.detail.provider)};return window.addEventListener(b,t),()=>window.removeEventListener(b,t)}export{S as C8WalletProvider,v as HttpClient,n as LocalStorageHelper,C as announceC8Provider,_ as onC8ProviderDiscovered};
|
package/dist/provider.d.ts
CHANGED
package/dist/types.d.ts
CHANGED
package/package.json
CHANGED