@thru/browser-sdk 0.0.4 → 0.0.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.d.ts +9 -6
- package/dist/index.js +34 -4
- package/dist/index.js.map +1 -1
- package/package.json +5 -5
- package/src/BrowserSDK.ts +42 -6
- package/src/index.ts +3 -9
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { AddressType, ConnectResult,
|
|
2
|
-
export { ConnectResult, IThruChain, SignMessageParams, SignMessageResult,
|
|
1
|
+
import { AddressType, ConnectResult, WalletAccount, IThruChain } from '@thru/chain-interfaces';
|
|
2
|
+
export { ConnectResult, IThruChain, SignMessageParams, SignMessageResult, WalletAccount } from '@thru/chain-interfaces';
|
|
3
3
|
import { ConnectMetadataInput } from '@thru/protocol';
|
|
4
|
-
import { Thru } from '@thru/thru-sdk';
|
|
4
|
+
import { Thru } from '@thru/thru-sdk/client';
|
|
5
5
|
export { ErrorCode } from '@thru/embedded-provider';
|
|
6
6
|
|
|
7
7
|
interface BrowserSDKConfig {
|
|
@@ -12,7 +12,7 @@ interface BrowserSDKConfig {
|
|
|
12
12
|
interface ConnectOptions {
|
|
13
13
|
metadata?: ConnectMetadataInput;
|
|
14
14
|
}
|
|
15
|
-
type SDKEvent = 'connect' | 'disconnect' | 'lock' | 'error';
|
|
15
|
+
type SDKEvent = 'connect' | 'disconnect' | 'lock' | 'error' | 'accountChanged';
|
|
16
16
|
type EventCallback = (...args: any[]) => void;
|
|
17
17
|
/**
|
|
18
18
|
* Browser SDK - Main entry point for dApp developers
|
|
@@ -45,9 +45,11 @@ declare class BrowserSDK {
|
|
|
45
45
|
*/
|
|
46
46
|
isConnected(): boolean;
|
|
47
47
|
/**
|
|
48
|
-
* Get all
|
|
48
|
+
* Get all accounts
|
|
49
49
|
*/
|
|
50
|
-
|
|
50
|
+
getAccounts(): WalletAccount[];
|
|
51
|
+
getSelectedAccount(): WalletAccount | null;
|
|
52
|
+
selectAccount(publicKey: string): Promise<WalletAccount>;
|
|
51
53
|
/**
|
|
52
54
|
* Get Thru chain API (iframe-backed signer)
|
|
53
55
|
*/
|
|
@@ -80,6 +82,7 @@ declare class BrowserSDK {
|
|
|
80
82
|
private resolveAppUrl;
|
|
81
83
|
private deriveAppName;
|
|
82
84
|
getThru(): Thru;
|
|
85
|
+
private refreshCachedAccounts;
|
|
83
86
|
}
|
|
84
87
|
|
|
85
88
|
export { BrowserSDK, type BrowserSDKConfig, type ConnectOptions, type EventCallback, type SDKEvent };
|
package/dist/index.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { EmbeddedProvider } from '@thru/embedded-provider';
|
|
2
2
|
export { ErrorCode } from '@thru/embedded-provider';
|
|
3
3
|
import { EMBEDDED_PROVIDER_EVENTS } from '@thru/protocol';
|
|
4
|
-
import { createThruClient } from '@thru/thru-sdk';
|
|
4
|
+
import { createThruClient } from '@thru/thru-sdk/client';
|
|
5
5
|
|
|
6
6
|
// ../chain-interfaces/dist/index.js
|
|
7
7
|
var AddressType = {
|
|
@@ -86,10 +86,20 @@ var BrowserSDK = class {
|
|
|
86
86
|
return this.provider.isConnected();
|
|
87
87
|
}
|
|
88
88
|
/**
|
|
89
|
-
* Get all
|
|
89
|
+
* Get all accounts
|
|
90
90
|
*/
|
|
91
|
-
|
|
92
|
-
|
|
91
|
+
getAccounts() {
|
|
92
|
+
const accounts = this.provider.getAccounts();
|
|
93
|
+
this.refreshCachedAccounts(accounts);
|
|
94
|
+
return accounts;
|
|
95
|
+
}
|
|
96
|
+
getSelectedAccount() {
|
|
97
|
+
return this.provider.getSelectedAccount();
|
|
98
|
+
}
|
|
99
|
+
async selectAccount(publicKey) {
|
|
100
|
+
const account = await this.provider.selectAccount(publicKey);
|
|
101
|
+
this.refreshCachedAccounts(this.provider.getAccounts(), account);
|
|
102
|
+
return account;
|
|
93
103
|
}
|
|
94
104
|
/**
|
|
95
105
|
* Get Thru chain API (iframe-backed signer)
|
|
@@ -150,6 +160,11 @@ var BrowserSDK = class {
|
|
|
150
160
|
this.emit("lock", data);
|
|
151
161
|
this.emit("disconnect", { reason: "locked" });
|
|
152
162
|
});
|
|
163
|
+
this.provider.on(EMBEDDED_PROVIDER_EVENTS.ACCOUNT_CHANGED, (data) => {
|
|
164
|
+
const account = data?.account ?? data;
|
|
165
|
+
this.refreshCachedAccounts(this.provider.getAccounts(), account ?? null);
|
|
166
|
+
this.emit("accountChanged", account);
|
|
167
|
+
});
|
|
153
168
|
}
|
|
154
169
|
/**
|
|
155
170
|
* Destroy SDK and cleanup
|
|
@@ -202,6 +217,21 @@ var BrowserSDK = class {
|
|
|
202
217
|
getThru() {
|
|
203
218
|
return this.thruClient;
|
|
204
219
|
}
|
|
220
|
+
refreshCachedAccounts(accounts, selectedAccount) {
|
|
221
|
+
let nextAccounts = accounts;
|
|
222
|
+
if (selectedAccount) {
|
|
223
|
+
const hasAccount = accounts.some((acc) => acc.address === selectedAccount.address);
|
|
224
|
+
if (!hasAccount) {
|
|
225
|
+
nextAccounts = [...accounts, selectedAccount];
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
if (this.lastConnectResult) {
|
|
229
|
+
this.lastConnectResult = {
|
|
230
|
+
...this.lastConnectResult,
|
|
231
|
+
accounts: nextAccounts
|
|
232
|
+
};
|
|
233
|
+
}
|
|
234
|
+
}
|
|
205
235
|
};
|
|
206
236
|
|
|
207
237
|
export { BrowserSDK };
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../chain-interfaces/src/types.ts","../src/BrowserSDK.ts"],"names":[],"mappings":";;;;;;AAAO,IAAM,WAAA,GAAc;EACzB,IAAA,EAAM;AACR,CAAA;AC2BO,IAAM,aAAN,MAAiB;AAAA,EAQtB,WAAA,CAAY,MAAA,GAA2B,EAAC,EAAG;AAN3C,IAAA,IAAA,CAAQ,cAAA,uBAAqB,GAAA,EAAkC;AAC/D,IAAA,IAAA,CAAQ,WAAA,GAAc,KAAA;AAEtB,IAAA,IAAA,CAAQ,eAAA,GAAiD,IAAA;AACzD,IAAA,IAAA,CAAQ,iBAAA,GAA0C,IAAA;AAGhD,IAAA,IAAA,CAAK,QAAA,GAAW,IAAI,gBAAA,CAAiB;AAAA,MACnC,WAAW,MAAA,CAAO,SAAA;AAAA,MAClB,YAAA,EAAc,MAAA,CAAO,YAAA,IAAgB,CAAC,YAAY,IAAI;AAAA,KACvD,CAAA;AAED,IAAA,IAAA,CAAK,aAAa,gBAAA,CAAiB;AAAA,MACjC,SAAS,MAAA,CAAO;AAAA,KACjB,CAAA;AAGD,IAAA,IAAA,CAAK,oBAAA,EAAqB;AAAA,EAC5B;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI,KAAK,WAAA,EAAa;AACpB,MAAA;AAAA,IACF;AAEA,IAAA,MAAM,IAAA,CAAK,SAAS,UAAA,EAAW;AAC/B,IAAA,IAAA,CAAK,WAAA,GAAc,IAAA;AAAA,EACrB;AAAA;AAAA;AAAA;AAAA;AAAA,EAMA,MAAM,QAAQ,OAAA,EAAkD;AAE9D,IAAA,IAAI,CAAC,KAAK,WAAA,EAAa;AACrB,MAAA,MAAM,KAAK,UAAA,EAAW;AAAA,IACxB;AAEA,IAAA,IAAI,KAAK,eAAA,EAAiB;AACxB,MAAA,OAAO,IAAA,CAAK,eAAA;AAAA,IACd;AAEA,IAAA,IAAI,IAAA,CAAK,iBAAA,IAAqB,IAAA,CAAK,QAAA,CAAS,aAAY,EAAG;AACzD,MAAA,OAAO,IAAA,CAAK,iBAAA;AAAA,IACd;AAEA,IAAA,IAAA,CAAK,IAAA,CAAK,SAAA,EAAW,EAAE,MAAA,EAAQ,cAAc,CAAA;AAE7C,IAAA,MAAM,YAAY,YAAY;AAC5B,MAAA,IAAI;AACF,QAAA,MAAM,QAAA,GAAW,IAAA,CAAK,eAAA,CAAgB,OAAA,EAAS,QAAQ,CAAA;AACvD,QAAA,MAAM,eAAA,GAAkB,QAAA,GAAW,EAAE,QAAA,EAAS,GAAI,KAAA,CAAA;AAClD,QAAA,MAAM,MAAA,GAAS,MAAM,IAAA,CAAK,QAAA,CAAS,QAAQ,eAAe,CAAA;AAC1D,QAAA,IAAA,CAAK,iBAAA,GAAoB,MAAA;AACzB,QAAA,IAAA,CAAK,IAAA,CAAK,WAAW,MAAM,CAAA;AAC3B,QAAA,OAAO,MAAA;AAAA,MACT,SAAS,KAAA,EAAO;AACd,QAAA,IAAA,CAAK,IAAA,CAAK,SAAS,KAAK,CAAA;AACxB,QAAA,MAAM,KAAA;AAAA,MACR,CAAA,SAAE;AACA,QAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AAAA,MACzB;AAAA,IACF,CAAA,GAAG;AAEH,IAAA,IAAA,CAAK,eAAA,GAAkB,QAAA;AACvB,IAAA,OAAO,QAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA,EAKA,MAAM,UAAA,GAA4B;AAChC,IAAA,IAAI;AACF,MAAA,MAAM,IAAA,CAAK,SAAS,UAAA,EAAW;AAC/B,MAAA,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,EAAE,CAAA;AAC1B,MAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,IAC3B,SAAS,KAAA,EAAO;AACd,MAAA,IAAA,CAAK,IAAA,CAAK,SAAS,KAAK,CAAA;AACxB,MAAA,MAAM,KAAA;AAAA,IACR;AAAA,EACF;AAAA;AAAA;AAAA;AAAA,EAKA,WAAA,GAAuB;AACrB,IAAA,OAAO,IAAA,CAAK,SAAS,WAAA,EAAY;AAAA,EACnC;AAAA;AAAA;AAAA;AAAA,EAKA,YAAA,GAAgC;AAC9B,IAAA,OAAO,IAAA,CAAK,SAAS,YAAA,EAAa;AAAA,EACpC;AAAA;AAAA;AAAA;AAAA,EAKA,IAAI,IAAA,GAAmB;AACrB,IAAA,OAAO,KAAK,QAAA,CAAS,IAAA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA,EAKA,EAAA,CAAG,OAAiB,QAAA,EAA+B;AACjD,IAAA,IAAI,CAAC,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,KAAK,CAAA,EAAG;AACnC,MAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,KAAA,kBAAO,IAAI,KAAK,CAAA;AAAA,IAC1C;AACA,IAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,KAAK,CAAA,CAAG,IAAI,QAAQ,CAAA;AAAA,EAC9C;AAAA;AAAA;AAAA;AAAA,EAKA,GAAA,CAAI,OAAiB,QAAA,EAA+B;AAClD,IAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,KAAK,CAAA,EAAG,OAAO,QAAQ,CAAA;AAAA,EACjD;AAAA;AAAA;AAAA;AAAA,EAKA,IAAA,CAAK,OAAiB,QAAA,EAA+B;AACnD,IAAA,MAAM,eAAA,GAAkB,IAAI,IAAA,KAAgB;AAC1C,MAAA,QAAA,CAAS,GAAG,IAAI,CAAA;AAChB,MAAA,IAAA,CAAK,GAAA,CAAI,OAAO,eAAe,CAAA;AAAA,IACjC,CAAA;AACA,IAAA,IAAA,CAAK,EAAA,CAAG,OAAO,eAAe,CAAA;AAAA,EAChC;AAAA;AAAA;AAAA;AAAA,EAKQ,IAAA,CAAK,OAAiB,IAAA,EAAkB;AAC9C,IAAA,IAAA,CAAK,cAAA,CAAe,GAAA,CAAI,KAAK,CAAA,EAAG,QAAQ,CAAA,QAAA,KAAY;AAClD,MAAA,IAAI;AACF,QAAA,QAAA,CAAS,IAAI,CAAA;AAAA,MACf,SAAS,KAAA,EAAO;AACd,QAAA,OAAA,CAAQ,KAAA,CAAM,CAAA,gCAAA,EAAmC,KAAK,CAAA,CAAA,CAAA,EAAK,KAAK,CAAA;AAAA,MAClE;AAAA,IACF,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKQ,oBAAA,GAA6B;AAEnC,IAAA,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,wBAAA,CAAyB,OAAA,EAAS,CAAC,IAAA,KAAc;AAAA,IAElE,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,wBAAA,CAAyB,UAAA,EAAY,CAAC,IAAA,KAAc;AACnE,MAAA,IAAA,CAAK,IAAA,CAAK,cAAc,IAAI,CAAA;AAAA,IAC9B,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,wBAAA,CAAyB,KAAA,EAAO,CAAC,IAAA,KAAc;AAC9D,MAAA,IAAA,CAAK,IAAA,CAAK,SAAS,IAAI,CAAA;AAAA,IACzB,CAAC,CAAA;AAED,IAAA,IAAA,CAAK,QAAA,CAAS,EAAA,CAAG,wBAAA,CAAyB,IAAA,EAAM,CAAC,IAAA,KAAc;AAC7D,MAAA,IAAA,CAAK,IAAA,CAAK,QAAQ,IAAI,CAAA;AACtB,MAAA,IAAA,CAAK,IAAA,CAAK,YAAA,EAAc,EAAE,MAAA,EAAQ,UAAU,CAAA;AAAA,IAC9C,CAAC,CAAA;AAAA,EACH;AAAA;AAAA;AAAA;AAAA,EAKA,OAAA,GAAgB;AACd,IAAA,IAAA,CAAK,SAAS,OAAA,EAAQ;AACtB,IAAA,IAAA,CAAK,eAAe,KAAA,EAAM;AAC1B,IAAA,IAAA,CAAK,WAAA,GAAc,KAAA;AACnB,IAAA,IAAA,CAAK,eAAA,GAAkB,IAAA;AACvB,IAAA,IAAA,CAAK,iBAAA,GAAoB,IAAA;AAAA,EAC3B;AAAA,EAEQ,gBAAgB,KAAA,EAAgE;AACtF,IAAA,MAAM,gBAAgB,OAAO,MAAA,KAAW,WAAA,GAAc,MAAA,CAAO,SAAS,MAAA,GAAS,MAAA;AAC/E,IAAA,IAAI,CAAC,aAAA,IAAiB,CAAC,KAAA,EAAO;AAC5B,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,IAAS,aAAA;AAC9B,IAAA,MAAM,MAAA,GAAS,IAAA,CAAK,aAAA,CAAc,aAAA,EAAe,OAAO,MAAM,CAAA;AAC9D,IAAA,MAAM,UAAU,KAAA,EAAO,OAAA,IAAW,IAAA,CAAK,aAAA,CAAc,UAAU,KAAK,CAAA;AAEpE,IAAA,MAAM,WAAiC,EAAC;AACxC,IAAA,IAAI,KAAA,WAAgB,KAAA,GAAQ,KAAA;AAC5B,IAAA,IAAI,MAAA,WAAiB,MAAA,GAAS,MAAA;AAC9B,IAAA,IAAI,OAAA,WAAkB,OAAA,GAAU,OAAA;AAChC,IAAA,IAAI,KAAA,EAAO,QAAA,EAAU,QAAA,CAAS,QAAA,GAAW,KAAA,CAAM,QAAA;AAE/C,IAAA,OAAO,QAAA;AAAA,EACT;AAAA,EAEQ,aAAA,CAAc,eAAwB,WAAA,EAA0C;AACtF,IAAA,MAAM,YAAY,WAAA,IAAe,aAAA;AACjC,IAAA,IAAI,CAAC,SAAA,EAAW;AACd,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,GAAA,GAAM,IAAI,GAAA,CAAI,SAAA,EAAW,aAAa,CAAA;AAC5C,MAAA,OAAO,IAAI,QAAA,EAAS;AAAA,IACtB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,aAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEQ,cAAc,MAAA,EAAqC;AACzD,IAAA,IAAI,CAAC,MAAA,EAAQ;AACX,MAAA,OAAO,MAAA;AAAA,IACT;AAEA,IAAA,IAAI;AACF,MAAA,MAAM,QAAA,GAAW,IAAI,GAAA,CAAI,MAAM,CAAA,CAAE,QAAA;AACjC,MAAA,OAAO,QAAA,IAAY,MAAA;AAAA,IACrB,CAAA,CAAA,MAAQ;AACN,MAAA,OAAO,MAAA;AAAA,IACT;AAAA,EACF;AAAA,EAEO,OAAA,GAAgB;AACrB,IAAA,OAAO,IAAA,CAAK,UAAA;AAAA,EACd;AACF","file":"index.js","sourcesContent":["export const AddressType = {\n THRU: 'thru',\n} as const;\n\nexport type AddressType = typeof AddressType[keyof typeof AddressType];\n\nexport interface WalletAddress {\n addressType: AddressType;\n address: string;\n}\n\nexport interface AppMetadata {\n appId: string;\n appName: string;\n appUrl: string;\n imageUrl?: string;\n}\n\nexport interface ConnectResult {\n walletId?: string;\n addresses: WalletAddress[];\n status?: 'pending' | 'completed';\n metadata?: AppMetadata;\n}\n\nexport interface ConnectedApp {\n accountId: number;\n appId: string;\n origin: string;\n metadata: AppMetadata;\n connectedAt: number;\n updatedAt: number;\n}\n\nexport interface SignMessageParams {\n message: string | Uint8Array;\n networkId: string;\n}\n\nexport interface SignMessageResult {\n signature: Uint8Array;\n publicKey: string;\n}\n","import type {\n AddressType as AddressTypeValue,\n ConnectResult,\n IThruChain,\n WalletAddress,\n} from '@thru/chain-interfaces';\nimport { AddressType } from '@thru/chain-interfaces';\nimport { EmbeddedProvider } from '@thru/embedded-provider';\nimport { EMBEDDED_PROVIDER_EVENTS, type ConnectMetadataInput } from '@thru/protocol';\nimport { createThruClient, Thru } from '@thru/thru-sdk';\n\nexport interface BrowserSDKConfig {\n iframeUrl?: string;\n addressTypes?: AddressTypeValue[];\n rpcUrl?: string;\n}\n\nexport interface ConnectOptions {\n metadata?: ConnectMetadataInput;\n}\n\nexport type SDKEvent = 'connect' | 'disconnect' | 'lock' | 'error';\n\nexport type EventCallback = (...args: any[]) => void;\n\n/**\n * Browser SDK - Main entry point for dApp developers\n * Wraps EmbeddedProvider with a clean, simple API\n */\nexport class BrowserSDK {\n private provider: EmbeddedProvider;\n private eventListeners = new Map<SDKEvent, Set<EventCallback>>();\n private initialized = false;\n private thruClient: Thru;\n private connectInFlight: Promise<ConnectResult> | null = null;\n private lastConnectResult: ConnectResult | null = null;\n\n constructor(config: BrowserSDKConfig = {}) {\n this.provider = new EmbeddedProvider({\n iframeUrl: config.iframeUrl,\n addressTypes: config.addressTypes || [AddressType.THRU],\n });\n\n this.thruClient = createThruClient({\n baseUrl: config.rpcUrl,\n });\n\n // Forward provider events to SDK events\n this.setupEventForwarding();\n }\n\n /**\n * Initialize the SDK (creates iframe)\n * Must be called before using the SDK\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.provider.initialize();\n this.initialized = true;\n }\n\n /**\n * Connect to wallet\n * Shows wallet modal and requests connection\n */\n async connect(options?: ConnectOptions): Promise<ConnectResult> {\n // Auto-initialize if not done yet\n if (!this.initialized) {\n await this.initialize();\n }\n\n if (this.connectInFlight) {\n return this.connectInFlight;\n }\n\n if (this.lastConnectResult && this.provider.isConnected()) {\n return this.lastConnectResult;\n }\n\n this.emit('connect', { status: 'connecting' });\n\n const inFlight = (async () => {\n try {\n const metadata = this.resolveMetadata(options?.metadata);\n const providerOptions = metadata ? { metadata } : undefined;\n const result = await this.provider.connect(providerOptions);\n this.lastConnectResult = result;\n this.emit('connect', result);\n return result;\n } catch (error) {\n this.emit('error', error);\n throw error;\n } finally {\n this.connectInFlight = null;\n }\n })();\n\n this.connectInFlight = inFlight;\n return inFlight;\n }\n\n /**\n * Disconnect from wallet\n */\n async disconnect(): Promise<void> {\n try {\n await this.provider.disconnect();\n this.emit('disconnect', {});\n this.lastConnectResult = null;\n } catch (error) {\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.provider.isConnected();\n }\n\n /**\n * Get all addresses\n */\n getAddresses(): WalletAddress[] {\n return this.provider.getAddresses();\n }\n\n /**\n * Get Thru chain API (iframe-backed signer)\n */\n get thru(): IThruChain {\n return this.provider.thru;\n }\n\n /**\n * Event emitter: on\n */\n on(event: SDKEvent, callback: EventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Event emitter: off\n */\n off(event: SDKEvent, callback: EventCallback): void {\n this.eventListeners.get(event)?.delete(callback);\n }\n\n /**\n * Event emitter: once (listen once and auto-remove)\n */\n once(event: SDKEvent, callback: EventCallback): void {\n const wrappedCallback = (...args: any[]) => {\n callback(...args);\n this.off(event, wrappedCallback);\n };\n this.on(event, wrappedCallback);\n }\n\n /**\n * Emit event to all listeners\n */\n private emit(event: SDKEvent, data?: any): void {\n this.eventListeners.get(event)?.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in SDK event listener for ${event}:`, error);\n }\n });\n }\n\n /**\n * Set up event forwarding from provider to SDK\n */\n private setupEventForwarding(): void {\n // Forward all relevant provider events to SDK events\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.CONNECT, (data: any) => {\n // Already handled in connect() method\n });\n\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.DISCONNECT, (data: any) => {\n this.emit('disconnect', data);\n });\n\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.ERROR, (data: any) => {\n this.emit('error', data);\n });\n\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.LOCK, (data: any) => {\n this.emit('lock', data);\n this.emit('disconnect', { reason: 'locked' });\n });\n }\n\n /**\n * Destroy SDK and cleanup\n */\n destroy(): void {\n this.provider.destroy();\n this.eventListeners.clear();\n this.initialized = false;\n this.connectInFlight = null;\n this.lastConnectResult = null;\n }\n\n private resolveMetadata(input?: ConnectMetadataInput): ConnectMetadataInput | undefined {\n const defaultOrigin = typeof window !== 'undefined' ? window.location.origin : undefined;\n if (!defaultOrigin && !input) {\n return undefined;\n }\n\n const appId = input?.appId || defaultOrigin;\n const appUrl = this.resolveAppUrl(defaultOrigin, input?.appUrl);\n const appName = input?.appName || this.deriveAppName(appUrl ?? appId);\n\n const metadata: ConnectMetadataInput = {};\n if (appId) metadata.appId = appId;\n if (appUrl) metadata.appUrl = appUrl;\n if (appName) metadata.appName = appName;\n if (input?.imageUrl) metadata.imageUrl = input.imageUrl;\n\n return metadata;\n }\n\n private resolveAppUrl(defaultOrigin?: string, providedUrl?: string): string | undefined {\n const candidate = providedUrl || defaultOrigin;\n if (!candidate) {\n return undefined;\n }\n\n try {\n const url = new URL(candidate, defaultOrigin);\n return url.toString();\n } catch {\n return defaultOrigin;\n }\n }\n\n private deriveAppName(source?: string): string | undefined {\n if (!source) {\n return undefined;\n }\n\n try {\n const hostname = new URL(source).hostname;\n return hostname || source;\n } catch {\n return source;\n }\n }\n\n public getThru(): Thru {\n return this.thruClient;\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../chain-interfaces/src/types.ts","../src/BrowserSDK.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["export const AddressType = {\n THRU: 'thru',\n} as const;\n\nexport type AddressType = typeof AddressType[keyof typeof AddressType];\n\nexport interface WalletAccount {\n accountType: AddressType;\n address: string;\n label: string;\n}\n\nexport interface AppMetadata {\n appId: string;\n appName: string;\n appUrl: string;\n imageUrl?: string;\n}\n\nexport interface ConnectResult {\n walletId?: string;\n accounts: WalletAccount[];\n status?: 'pending' | 'completed';\n metadata?: AppMetadata;\n}\n\nexport interface ConnectedApp {\n accountId: number;\n appId: string;\n origin: string;\n metadata: AppMetadata;\n connectedAt: number;\n updatedAt: number;\n}\n\nexport interface SignMessageParams {\n message: string | Uint8Array;\n networkId: string;\n}\n\nexport interface SignMessageResult {\n signature: Uint8Array;\n publicKey: string;\n}\n","import type {\n AddressType as AddressTypeValue,\n ConnectResult,\n IThruChain,\n WalletAccount,\n} from '@thru/chain-interfaces';\nimport { AddressType } from '@thru/chain-interfaces';\nimport { EmbeddedProvider } from '@thru/embedded-provider';\nimport { EMBEDDED_PROVIDER_EVENTS, type ConnectMetadataInput } from '@thru/protocol';\nimport { createThruClient, Thru } from '@thru/thru-sdk/client';\n\nexport interface BrowserSDKConfig {\n iframeUrl?: string;\n addressTypes?: AddressTypeValue[];\n rpcUrl?: string;\n}\n\nexport interface ConnectOptions {\n metadata?: ConnectMetadataInput;\n}\n\nexport type SDKEvent = 'connect' | 'disconnect' | 'lock' | 'error' | 'accountChanged';\n\nexport type EventCallback = (...args: any[]) => void;\n\n/**\n * Browser SDK - Main entry point for dApp developers\n * Wraps EmbeddedProvider with a clean, simple API\n */\nexport class BrowserSDK {\n private provider: EmbeddedProvider;\n private eventListeners = new Map<SDKEvent, Set<EventCallback>>();\n private initialized = false;\n private thruClient: Thru;\n private connectInFlight: Promise<ConnectResult> | null = null;\n private lastConnectResult: ConnectResult | null = null;\n\n constructor(config: BrowserSDKConfig = {}) {\n this.provider = new EmbeddedProvider({\n iframeUrl: config.iframeUrl,\n addressTypes: config.addressTypes || [AddressType.THRU],\n });\n\n this.thruClient = createThruClient({\n baseUrl: config.rpcUrl,\n });\n\n // Forward provider events to SDK events\n this.setupEventForwarding();\n }\n\n /**\n * Initialize the SDK (creates iframe)\n * Must be called before using the SDK\n */\n async initialize(): Promise<void> {\n if (this.initialized) {\n return;\n }\n\n await this.provider.initialize();\n this.initialized = true;\n }\n\n /**\n * Connect to wallet\n * Shows wallet modal and requests connection\n */\n async connect(options?: ConnectOptions): Promise<ConnectResult> {\n // Auto-initialize if not done yet\n if (!this.initialized) {\n await this.initialize();\n }\n\n if (this.connectInFlight) {\n return this.connectInFlight;\n }\n\n if (this.lastConnectResult && this.provider.isConnected()) {\n return this.lastConnectResult;\n }\n\n this.emit('connect', { status: 'connecting' });\n\n const inFlight = (async () => {\n try {\n const metadata = this.resolveMetadata(options?.metadata);\n const providerOptions = metadata ? { metadata } : undefined;\n const result = await this.provider.connect(providerOptions);\n this.lastConnectResult = result;\n this.emit('connect', result);\n return result;\n } catch (error) {\n this.emit('error', error);\n throw error;\n } finally {\n this.connectInFlight = null;\n }\n })();\n\n this.connectInFlight = inFlight;\n return inFlight;\n }\n\n /**\n * Disconnect from wallet\n */\n async disconnect(): Promise<void> {\n try {\n await this.provider.disconnect();\n this.emit('disconnect', {});\n this.lastConnectResult = null;\n } catch (error) {\n this.emit('error', error);\n throw error;\n }\n }\n\n /**\n * Check if connected\n */\n isConnected(): boolean {\n return this.provider.isConnected();\n }\n\n /**\n * Get all accounts\n */\n getAccounts(): WalletAccount[] {\n const accounts = this.provider.getAccounts();\n this.refreshCachedAccounts(accounts);\n return accounts;\n }\n\n getSelectedAccount(): WalletAccount | null {\n return this.provider.getSelectedAccount();\n }\n\n async selectAccount(publicKey: string): Promise<WalletAccount> {\n const account = await this.provider.selectAccount(publicKey);\n this.refreshCachedAccounts(this.provider.getAccounts(), account);\n return account;\n }\n\n /**\n * Get Thru chain API (iframe-backed signer)\n */\n get thru(): IThruChain {\n return this.provider.thru;\n }\n\n /**\n * Event emitter: on\n */\n on(event: SDKEvent, callback: EventCallback): void {\n if (!this.eventListeners.has(event)) {\n this.eventListeners.set(event, new Set());\n }\n this.eventListeners.get(event)!.add(callback);\n }\n\n /**\n * Event emitter: off\n */\n off(event: SDKEvent, callback: EventCallback): void {\n this.eventListeners.get(event)?.delete(callback);\n }\n\n /**\n * Event emitter: once (listen once and auto-remove)\n */\n once(event: SDKEvent, callback: EventCallback): void {\n const wrappedCallback = (...args: any[]) => {\n callback(...args);\n this.off(event, wrappedCallback);\n };\n this.on(event, wrappedCallback);\n }\n\n /**\n * Emit event to all listeners\n */\n private emit(event: SDKEvent, data?: any): void {\n this.eventListeners.get(event)?.forEach(callback => {\n try {\n callback(data);\n } catch (error) {\n console.error(`Error in SDK event listener for ${event}:`, error);\n }\n });\n }\n\n /**\n * Set up event forwarding from provider to SDK\n */\n private setupEventForwarding(): void {\n // Forward all relevant provider events to SDK events\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.CONNECT, (data: any) => {\n // Already handled in connect() method\n });\n\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.DISCONNECT, (data: any) => {\n this.emit('disconnect', data);\n });\n\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.ERROR, (data: any) => {\n this.emit('error', data);\n });\n\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.LOCK, (data: any) => {\n this.emit('lock', data);\n this.emit('disconnect', { reason: 'locked' });\n });\n\n this.provider.on(EMBEDDED_PROVIDER_EVENTS.ACCOUNT_CHANGED, (data: any) => {\n const account = data?.account ?? data;\n this.refreshCachedAccounts(this.provider.getAccounts(), account ?? null);\n this.emit('accountChanged', account);\n });\n }\n\n /**\n * Destroy SDK and cleanup\n */\n destroy(): void {\n this.provider.destroy();\n this.eventListeners.clear();\n this.initialized = false;\n this.connectInFlight = null;\n this.lastConnectResult = null;\n }\n\n private resolveMetadata(input?: ConnectMetadataInput): ConnectMetadataInput | undefined {\n const defaultOrigin = typeof window !== 'undefined' ? window.location.origin : undefined;\n if (!defaultOrigin && !input) {\n return undefined;\n }\n\n const appId = input?.appId || defaultOrigin;\n const appUrl = this.resolveAppUrl(defaultOrigin, input?.appUrl);\n const appName = input?.appName || this.deriveAppName(appUrl ?? appId);\n\n const metadata: ConnectMetadataInput = {};\n if (appId) metadata.appId = appId;\n if (appUrl) metadata.appUrl = appUrl;\n if (appName) metadata.appName = appName;\n if (input?.imageUrl) metadata.imageUrl = input.imageUrl;\n\n return metadata;\n }\n\n private resolveAppUrl(defaultOrigin?: string, providedUrl?: string): string | undefined {\n const candidate = providedUrl || defaultOrigin;\n if (!candidate) {\n return undefined;\n }\n\n try {\n const url = new URL(candidate, defaultOrigin);\n return url.toString();\n } catch {\n return defaultOrigin;\n }\n }\n\n private deriveAppName(source?: string): string | undefined {\n if (!source) {\n return undefined;\n }\n\n try {\n const hostname = new URL(source).hostname;\n return hostname || source;\n } catch {\n return source;\n }\n }\n\n public getThru(): Thru {\n return this.thruClient;\n }\n\n private refreshCachedAccounts(accounts: WalletAccount[], selectedAccount?: WalletAccount | null): void {\n let nextAccounts = accounts;\n\n if (selectedAccount) {\n const hasAccount = accounts.some(acc => acc.address === selectedAccount.address);\n if (!hasAccount) {\n nextAccounts = [...accounts, selectedAccount];\n }\n }\n\n if (this.lastConnectResult) {\n this.lastConnectResult = {\n ...this.lastConnectResult,\n accounts: nextAccounts,\n };\n }\n }\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thru/browser-sdk",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.6",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"types": "./dist/index.d.ts",
|
|
@@ -11,10 +11,10 @@
|
|
|
11
11
|
}
|
|
12
12
|
},
|
|
13
13
|
"dependencies": {
|
|
14
|
-
"@thru/embedded-provider": "0.0.
|
|
15
|
-
"@thru/chain-interfaces": "0.0.
|
|
16
|
-
"@thru/protocol": "0.0.
|
|
17
|
-
"@thru/thru-sdk": "0.0.
|
|
14
|
+
"@thru/embedded-provider": "0.0.6",
|
|
15
|
+
"@thru/chain-interfaces": "0.0.6",
|
|
16
|
+
"@thru/protocol": "0.0.6",
|
|
17
|
+
"@thru/thru-sdk": "0.0.6"
|
|
18
18
|
},
|
|
19
19
|
"scripts": {
|
|
20
20
|
"build": "tsup",
|
package/src/BrowserSDK.ts
CHANGED
|
@@ -2,12 +2,12 @@ import type {
|
|
|
2
2
|
AddressType as AddressTypeValue,
|
|
3
3
|
ConnectResult,
|
|
4
4
|
IThruChain,
|
|
5
|
-
|
|
5
|
+
WalletAccount,
|
|
6
6
|
} from '@thru/chain-interfaces';
|
|
7
7
|
import { AddressType } from '@thru/chain-interfaces';
|
|
8
8
|
import { EmbeddedProvider } from '@thru/embedded-provider';
|
|
9
9
|
import { EMBEDDED_PROVIDER_EVENTS, type ConnectMetadataInput } from '@thru/protocol';
|
|
10
|
-
import { createThruClient, Thru } from '@thru/thru-sdk';
|
|
10
|
+
import { createThruClient, Thru } from '@thru/thru-sdk/client';
|
|
11
11
|
|
|
12
12
|
export interface BrowserSDKConfig {
|
|
13
13
|
iframeUrl?: string;
|
|
@@ -19,7 +19,7 @@ export interface ConnectOptions {
|
|
|
19
19
|
metadata?: ConnectMetadataInput;
|
|
20
20
|
}
|
|
21
21
|
|
|
22
|
-
export type SDKEvent = 'connect' | 'disconnect' | 'lock' | 'error';
|
|
22
|
+
export type SDKEvent = 'connect' | 'disconnect' | 'lock' | 'error' | 'accountChanged';
|
|
23
23
|
|
|
24
24
|
export type EventCallback = (...args: any[]) => void;
|
|
25
25
|
|
|
@@ -124,10 +124,22 @@ export class BrowserSDK {
|
|
|
124
124
|
}
|
|
125
125
|
|
|
126
126
|
/**
|
|
127
|
-
* Get all
|
|
127
|
+
* Get all accounts
|
|
128
128
|
*/
|
|
129
|
-
|
|
130
|
-
|
|
129
|
+
getAccounts(): WalletAccount[] {
|
|
130
|
+
const accounts = this.provider.getAccounts();
|
|
131
|
+
this.refreshCachedAccounts(accounts);
|
|
132
|
+
return accounts;
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
getSelectedAccount(): WalletAccount | null {
|
|
136
|
+
return this.provider.getSelectedAccount();
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
async selectAccount(publicKey: string): Promise<WalletAccount> {
|
|
140
|
+
const account = await this.provider.selectAccount(publicKey);
|
|
141
|
+
this.refreshCachedAccounts(this.provider.getAccounts(), account);
|
|
142
|
+
return account;
|
|
131
143
|
}
|
|
132
144
|
|
|
133
145
|
/**
|
|
@@ -199,6 +211,12 @@ export class BrowserSDK {
|
|
|
199
211
|
this.emit('lock', data);
|
|
200
212
|
this.emit('disconnect', { reason: 'locked' });
|
|
201
213
|
});
|
|
214
|
+
|
|
215
|
+
this.provider.on(EMBEDDED_PROVIDER_EVENTS.ACCOUNT_CHANGED, (data: any) => {
|
|
216
|
+
const account = data?.account ?? data;
|
|
217
|
+
this.refreshCachedAccounts(this.provider.getAccounts(), account ?? null);
|
|
218
|
+
this.emit('accountChanged', account);
|
|
219
|
+
});
|
|
202
220
|
}
|
|
203
221
|
|
|
204
222
|
/**
|
|
@@ -261,4 +279,22 @@ export class BrowserSDK {
|
|
|
261
279
|
public getThru(): Thru {
|
|
262
280
|
return this.thruClient;
|
|
263
281
|
}
|
|
282
|
+
|
|
283
|
+
private refreshCachedAccounts(accounts: WalletAccount[], selectedAccount?: WalletAccount | null): void {
|
|
284
|
+
let nextAccounts = accounts;
|
|
285
|
+
|
|
286
|
+
if (selectedAccount) {
|
|
287
|
+
const hasAccount = accounts.some(acc => acc.address === selectedAccount.address);
|
|
288
|
+
if (!hasAccount) {
|
|
289
|
+
nextAccounts = [...accounts, selectedAccount];
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
if (this.lastConnectResult) {
|
|
294
|
+
this.lastConnectResult = {
|
|
295
|
+
...this.lastConnectResult,
|
|
296
|
+
accounts: nextAccounts,
|
|
297
|
+
};
|
|
298
|
+
}
|
|
299
|
+
}
|
|
264
300
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,19 +1,13 @@
|
|
|
1
1
|
// Main exports
|
|
2
2
|
export {
|
|
3
3
|
BrowserSDK,
|
|
4
|
-
type BrowserSDKConfig,
|
|
5
|
-
type SDKEvent,
|
|
6
|
-
type EventCallback,
|
|
7
|
-
type ConnectOptions,
|
|
4
|
+
type BrowserSDKConfig, type ConnectOptions, type EventCallback, type SDKEvent
|
|
8
5
|
} from './BrowserSDK';
|
|
9
6
|
|
|
10
7
|
// Re-export types from chain-interfaces for convenience
|
|
11
8
|
export type {
|
|
12
|
-
IThruChain,
|
|
13
|
-
|
|
14
|
-
ConnectResult,
|
|
15
|
-
SignMessageParams,
|
|
16
|
-
SignMessageResult,
|
|
9
|
+
ConnectResult, IThruChain, SignMessageParams,
|
|
10
|
+
SignMessageResult, WalletAccount
|
|
17
11
|
} from '@thru/chain-interfaces';
|
|
18
12
|
|
|
19
13
|
// Re-export error codes from embedded-provider
|