@thru/wallet 0.2.22

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.
Files changed (69) hide show
  1. package/README.md +67 -0
  2. package/android/build.gradle +37 -0
  3. package/android/src/main/AndroidManifest.xml +1 -0
  4. package/android/src/main/java/org/thru/walletnative/ThruWebViewBridgeModule.kt +77 -0
  5. package/app.plugin.cjs +101 -0
  6. package/dist/BrowserSDK-CpRFiJsW.d.ts +409 -0
  7. package/dist/index.d.ts +23 -0
  8. package/dist/index.js +941 -0
  9. package/dist/index.js.map +1 -0
  10. package/dist/native/react.d.ts +109 -0
  11. package/dist/native/react.js +2381 -0
  12. package/dist/native/react.js.map +1 -0
  13. package/dist/native.d.ts +329 -0
  14. package/dist/native.js +1126 -0
  15. package/dist/native.js.map +1 -0
  16. package/dist/react-ui.d.ts +5 -0
  17. package/dist/react-ui.js +266 -0
  18. package/dist/react-ui.js.map +1 -0
  19. package/dist/react.d.ts +66 -0
  20. package/dist/react.js +1151 -0
  21. package/dist/react.js.map +1 -0
  22. package/expo-module.config.json +6 -0
  23. package/package.json +114 -0
  24. package/src/BrowserSDK.ts +315 -0
  25. package/src/index.ts +27 -0
  26. package/src/interfaces/IThruChain.ts +37 -0
  27. package/src/interfaces/accounts.ts +61 -0
  28. package/src/interfaces/index.ts +9 -0
  29. package/src/interfaces/types.ts +95 -0
  30. package/src/native/NativeSDK.test.ts +819 -0
  31. package/src/native/NativeSDK.ts +773 -0
  32. package/src/native/index.ts +39 -0
  33. package/src/native/provider/NativeProvider.ts +363 -0
  34. package/src/native/provider/WebViewBridge.test.ts +339 -0
  35. package/src/native/provider/WebViewBridge.ts +339 -0
  36. package/src/native/provider/chains/ThruChain.ts +85 -0
  37. package/src/native/provider/shell.html +88 -0
  38. package/src/native/provider/shell.test.ts +56 -0
  39. package/src/native/provider/shell.ts +111 -0
  40. package/src/native/provider/shims-html.d.ts +4 -0
  41. package/src/native/react/ThruContext.ts +37 -0
  42. package/src/native/react/ThruProvider.tsx +168 -0
  43. package/src/native/react/ThruWalletSheet.tsx +1162 -0
  44. package/src/native/react/android-webauthn.ts +37 -0
  45. package/src/native/react/hooks/useAccounts.ts +35 -0
  46. package/src/native/react/hooks/useThru.ts +11 -0
  47. package/src/native/react/hooks/useWallet.ts +71 -0
  48. package/src/native/react/hooks/useWalletAvailability.ts +31 -0
  49. package/src/native/react/hooks/waitForWallet.ts +21 -0
  50. package/src/native/react/index.ts +29 -0
  51. package/src/protocol/index.ts +2 -0
  52. package/src/protocol/postMessage.ts +283 -0
  53. package/src/protocol/walletState.ts +12 -0
  54. package/src/provider/EmbeddedProvider.ts +330 -0
  55. package/src/provider/IframeManager.ts +438 -0
  56. package/src/provider/chains/ThruChain.ts +86 -0
  57. package/src/provider/index.ts +17 -0
  58. package/src/provider/types/messages.ts +37 -0
  59. package/src/react/ThruContext.ts +31 -0
  60. package/src/react/ThruProvider.tsx +169 -0
  61. package/src/react/hooks/useAccounts.ts +38 -0
  62. package/src/react/hooks/useThru.ts +11 -0
  63. package/src/react/hooks/useWallet.ts +81 -0
  64. package/src/react/index.ts +30 -0
  65. package/src/react-ui/ThruAccountSwitcher.tsx +187 -0
  66. package/src/react-ui/custom.d.ts +8 -0
  67. package/src/react-ui/index.ts +1 -0
  68. package/src/static/logo.png +0 -0
  69. package/src/static/logomark_red.svg +11 -0
@@ -0,0 +1,37 @@
1
+ /* Thin TypeScript shim over the Android Expo Module that wires
2
+ * react-native-webview to androidx.webkit's
3
+ * `setWebAuthnSupport`. On non-Android platforms (iOS, web)
4
+ * this is a no-op - WKWebView gets WebAuthn for free once the host
5
+ * declares `WKAppBoundDomains` (handled by our Expo config plugin). */
6
+
7
+ import { Platform } from 'react-native';
8
+ import { requireOptionalNativeModule } from 'expo-modules-core';
9
+
10
+ /* `requireOptionalNativeModule` returns null when the module isn't
11
+ * linked (e.g. Expo Go without the dev client, or non-Android). */
12
+ interface ThruWebViewBridgeNativeModule {
13
+ enableWebAuthnSupport: (viewTag?: number | null) => Promise<boolean>;
14
+ }
15
+
16
+ const Native = requireOptionalNativeModule(
17
+ 'ThruWebViewBridge'
18
+ ) as ThruWebViewBridgeNativeModule | null;
19
+
20
+ /**
21
+ * Tell the mounted WebView to route WebAuthn calls through Credential
22
+ * Manager. Returns true if the call landed, false on
23
+ * platforms where it isn't needed or supported.
24
+ *
25
+ * Idempotent; safe to call on every WebView mount.
26
+ */
27
+ export async function enableWebAuthnSupport(viewTag?: number | null): Promise<boolean> {
28
+ if (Platform.OS !== 'android') return false; /* iOS / web: no-op. */
29
+ if (!Native) return false; /* Module not linked (Expo Go fallback). */
30
+ try {
31
+ return await Native.enableWebAuthnSupport(viewTag);
32
+ } catch (err) {
33
+ // eslint-disable-next-line no-console
34
+ console.warn('[@thru/wallet/native/react] enableWebAuthnSupport failed:', err);
35
+ return false;
36
+ }
37
+ }
@@ -0,0 +1,35 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import type { WalletAccount } from "../../../interfaces";
3
+ import { useThru } from './useThru';
4
+
5
+ export interface UseAccountsOptions {
6
+ /** Fired whenever the active account flips (initial pick or switch). */
7
+ onAccountSelect?: (account: WalletAccount) => void;
8
+ }
9
+
10
+ /**
11
+ * useAccounts - mirror of @thru/wallet/react's useAccounts. Subscribes to
12
+ * `selectedAccount` flips and invokes the consumer's callback on real
13
+ * changes (deduped against the previous address).
14
+ */
15
+ export function useAccounts({ onAccountSelect }: UseAccountsOptions = {}) {
16
+ const { accounts, selectedAccount, isConnected, isConnecting } = useThru();
17
+ const lastSeen = useRef<string | null>(null);
18
+
19
+ useEffect(() => {
20
+ if (!selectedAccount) {
21
+ lastSeen.current = null;
22
+ return;
23
+ }
24
+ if (lastSeen.current === selectedAccount.address) return;
25
+ lastSeen.current = selectedAccount.address;
26
+ onAccountSelect?.(selectedAccount);
27
+ }, [selectedAccount, onAccountSelect]);
28
+
29
+ return {
30
+ accounts,
31
+ selectedAccount,
32
+ isConnected,
33
+ isConnecting,
34
+ };
35
+ }
@@ -0,0 +1,11 @@
1
+ import { useContext } from 'react';
2
+ import { ThruContext, type ThruContextValue } from '../ThruContext';
3
+
4
+ /** Returns the full ThruContextValue. Throws if used outside <ThruProvider>. */
5
+ export function useThru(): ThruContextValue {
6
+ const ctx = useContext(ThruContext);
7
+ if (!ctx) {
8
+ throw new Error('useThru must be used inside <ThruProvider>');
9
+ }
10
+ return ctx;
11
+ }
@@ -0,0 +1,71 @@
1
+ import { useCallback, useEffect, useRef } from 'react';
2
+ import type { ConnectResult, IThruChain } from "../../../interfaces";
3
+ import type { ConnectOptions, SignInOptions } from "../../NativeSDK";
4
+ import { useThru } from './useThru';
5
+ import { waitForWallet } from './waitForWallet';
6
+
7
+ /**
8
+ * useWallet - mirror of @thru/wallet/react's useWallet. The `wallet` field
9
+ * exposes the chain interface (`provider.thru`); `connect` /
10
+ * `disconnect` proxy through the SDK.
11
+ */
12
+ export function useWallet() {
13
+ const {
14
+ wallet,
15
+ isConnected,
16
+ isConnecting,
17
+ accounts,
18
+ selectedAccount,
19
+ selectAccount,
20
+ manageAccounts,
21
+ walletAvailability,
22
+ } = useThru();
23
+ const walletRef = useRef(wallet);
24
+
25
+ useEffect(() => {
26
+ walletRef.current = wallet;
27
+ }, [wallet]);
28
+
29
+ const connect = useCallback(async (options?: ConnectOptions): Promise<ConnectResult> => {
30
+ const ready =
31
+ walletRef.current ?? (await waitForWallet(() => walletRef.current));
32
+ return ready.connect(options);
33
+ }, []);
34
+
35
+ const signIn = useCallback(async (options: SignInOptions): Promise<ConnectResult> => {
36
+ const ready =
37
+ walletRef.current ?? (await waitForWallet(() => walletRef.current));
38
+ return ready.signIn(options);
39
+ }, []);
40
+
41
+ const disconnect = useCallback(async (): Promise<void> => {
42
+ const ready =
43
+ walletRef.current ?? (await waitForWallet(() => walletRef.current));
44
+ await ready.disconnect();
45
+ }, []);
46
+
47
+ const refreshWalletAvailability = useCallback(async (options?: ConnectOptions) => {
48
+ const ready =
49
+ walletRef.current ?? (await waitForWallet(() => walletRef.current));
50
+ return ready.refreshWalletAvailability(options);
51
+ }, []);
52
+
53
+ return {
54
+ /** Chain interface (`provider.thru`); undefined until connected. */
55
+ wallet: wallet?.thru as IThruChain | undefined,
56
+ accounts,
57
+ connect,
58
+ signIn,
59
+ disconnect,
60
+ isConnected: isConnected && !!wallet,
61
+ isConnecting,
62
+ selectedAccount,
63
+ selectAccount,
64
+ manageAccounts,
65
+ walletAvailability,
66
+ hasPasskey: walletAvailability.hasPasskey,
67
+ hasWalletAccount: walletAvailability.hasWalletAccount,
68
+ isWalletAvailabilityLoading: walletAvailability.status === 'checking',
69
+ refreshWalletAvailability,
70
+ };
71
+ }
@@ -0,0 +1,31 @@
1
+ import { useEffect, useRef } from 'react';
2
+ import type { ConnectOptions } from "../../NativeSDK";
3
+ import { useThru } from './useThru';
4
+ import { waitForWallet } from './waitForWallet';
5
+
6
+ export function useWalletAvailability() {
7
+ const { wallet, walletAvailability } = useThru();
8
+ const walletRef = useRef(wallet);
9
+
10
+ useEffect(() => {
11
+ walletRef.current = wallet;
12
+ }, [wallet]);
13
+
14
+ const refreshWalletAvailability = async (options?: ConnectOptions) => {
15
+ const ready =
16
+ walletRef.current ?? (await waitForWallet(() => walletRef.current));
17
+ return ready.refreshWalletAvailability(options);
18
+ };
19
+
20
+ return {
21
+ walletAvailability,
22
+ refreshWalletAvailability,
23
+ hasPasskey: walletAvailability.hasPasskey,
24
+ hasWalletAccount: walletAvailability.hasWalletAccount,
25
+ isAuthorized: walletAvailability.isAuthorized,
26
+ isWalletAvailabilityLoading: walletAvailability.status === 'checking',
27
+ accounts: walletAvailability.accounts,
28
+ selectedAccount: walletAvailability.selectedAccount,
29
+ error: walletAvailability.error,
30
+ };
31
+ }
@@ -0,0 +1,21 @@
1
+ import type { NativeSDK } from "../../NativeSDK";
2
+
3
+ /** Spin until the SDK exists or `timeout` ms passes. */
4
+ export function waitForWallet(
5
+ getWallet: () => NativeSDK | null,
6
+ timeout = 5000,
7
+ interval = 100
8
+ ): Promise<NativeSDK> {
9
+ return new Promise((resolve, reject) => {
10
+ const start = Date.now();
11
+ const check = () => {
12
+ const sdk = getWallet();
13
+ if (sdk) return resolve(sdk);
14
+ if (Date.now() - start > timeout) {
15
+ return reject(new Error('NativeSDK not initialized in time'));
16
+ }
17
+ setTimeout(check, interval);
18
+ };
19
+ check();
20
+ });
21
+ }
@@ -0,0 +1,29 @@
1
+ export { ThruProvider } from './ThruProvider';
2
+ export type { ThruProviderProps } from './ThruProvider';
3
+ export { ThruContext } from './ThruContext';
4
+ export type { ThruContextValue } from './ThruContext';
5
+
6
+ export { ThruWalletSheet } from './ThruWalletSheet';
7
+ export type {
8
+ ThruWalletSheetProps,
9
+ ThruWalletSheetHandle,
10
+ } from './ThruWalletSheet';
11
+
12
+ export { useWallet } from './hooks/useWallet';
13
+ export { useWalletAvailability } from './hooks/useWalletAvailability';
14
+ export { useAccounts } from './hooks/useAccounts';
15
+ export { useThru } from './hooks/useThru';
16
+
17
+ export { enableWebAuthnSupport } from './android-webauthn';
18
+
19
+ export type {
20
+ WalletAccount,
21
+ ConnectResult,
22
+ } from "../../interfaces";
23
+
24
+ export type {
25
+ IosWebViewMode,
26
+ NativeSDKStorage,
27
+ WalletAvailability,
28
+ } from "../NativeSDK";
29
+ export type { ManageAccountsResult } from "../../protocol";
@@ -0,0 +1,2 @@
1
+ export * from './postMessage';
2
+ export * from './walletState';
@@ -0,0 +1,283 @@
1
+ import type {
2
+ AppMetadata,
3
+ ConnectResult,
4
+ ThruSigningContext,
5
+ WalletAccount,
6
+ } from "../interfaces";
7
+
8
+ export const POST_MESSAGE_REQUEST_TYPES = {
9
+ CONNECT: "connect",
10
+ DISCONNECT: "disconnect",
11
+ SIGN_MESSAGE: "signMessage",
12
+ SIGN_TRANSACTION: "signTransaction",
13
+ GET_ACCOUNTS: "getAccounts",
14
+ GET_CONNECTION_STATE: "getConnectionState",
15
+ GET_SIGNING_CONTEXT: "getSigningContext",
16
+ SELECT_ACCOUNT: "selectAccount",
17
+ MANAGE_ACCOUNTS: "manageAccounts",
18
+ } as const;
19
+
20
+ export type RequestType =
21
+ (typeof POST_MESSAGE_REQUEST_TYPES)[keyof typeof POST_MESSAGE_REQUEST_TYPES];
22
+
23
+ export const EMBEDDED_PROVIDER_EVENTS = {
24
+ CONNECT_START: "connect_start",
25
+ CONNECT: "connect",
26
+ DISCONNECT: "disconnect",
27
+ CONNECT_ERROR: "connect_error",
28
+ ERROR: "error",
29
+ LOCK: "lock",
30
+ UI_SHOW: "ui_show",
31
+ ACCOUNT_CHANGED: "account_changed",
32
+ } as const;
33
+
34
+ export type EmbeddedProviderEvent =
35
+ (typeof EMBEDDED_PROVIDER_EVENTS)[keyof typeof EMBEDDED_PROVIDER_EVENTS];
36
+
37
+ export const POST_MESSAGE_EVENT_TYPE = "event" as const;
38
+
39
+ export const IFRAME_READY_EVENT = "iframe:ready" as const;
40
+
41
+ export const DEFAULT_IFRAME_URL = "http://localhost:3000/embedded";
42
+
43
+ const REQUEST_ID_PREFIX = "req";
44
+
45
+ export const createRequestId = (prefix: string = REQUEST_ID_PREFIX): string => {
46
+ const random = Math.random().toString(36).slice(2, 11);
47
+ return `${prefix}_${Date.now()}_${random}`;
48
+ };
49
+
50
+ interface BaseRequest {
51
+ id: string;
52
+ origin: string;
53
+ }
54
+
55
+ export interface ConnectRequestMessage extends BaseRequest {
56
+ type: typeof POST_MESSAGE_REQUEST_TYPES.CONNECT;
57
+ payload: ConnectRequestPayload;
58
+ }
59
+
60
+ export interface DisconnectRequestMessage extends BaseRequest {
61
+ type: typeof POST_MESSAGE_REQUEST_TYPES.DISCONNECT;
62
+ payload?: undefined;
63
+ }
64
+
65
+ export interface SignMessageRequestMessage extends BaseRequest {
66
+ type: typeof POST_MESSAGE_REQUEST_TYPES.SIGN_MESSAGE;
67
+ payload: SignMessagePayload;
68
+ }
69
+
70
+ export interface SignTransactionRequestMessage extends BaseRequest {
71
+ type: typeof POST_MESSAGE_REQUEST_TYPES.SIGN_TRANSACTION;
72
+ payload: SignTransactionPayload;
73
+ }
74
+
75
+ export interface GetAccountsRequestMessage extends BaseRequest {
76
+ type: typeof POST_MESSAGE_REQUEST_TYPES.GET_ACCOUNTS;
77
+ payload?: undefined;
78
+ }
79
+
80
+ export interface GetConnectionStateRequestMessage extends BaseRequest {
81
+ type: typeof POST_MESSAGE_REQUEST_TYPES.GET_CONNECTION_STATE;
82
+ payload: ConnectRequestPayload;
83
+ }
84
+
85
+ export interface GetSigningContextRequestMessage extends BaseRequest {
86
+ type: typeof POST_MESSAGE_REQUEST_TYPES.GET_SIGNING_CONTEXT;
87
+ payload?: undefined;
88
+ }
89
+
90
+ export interface SelectAccountRequestMessage extends BaseRequest {
91
+ type: typeof POST_MESSAGE_REQUEST_TYPES.SELECT_ACCOUNT;
92
+ payload: SelectAccountPayload;
93
+ }
94
+
95
+ export interface ManageAccountsRequestMessage extends BaseRequest {
96
+ type: typeof POST_MESSAGE_REQUEST_TYPES.MANAGE_ACCOUNTS;
97
+ payload?: undefined;
98
+ }
99
+
100
+ export type PostMessageRequest =
101
+ | ConnectRequestMessage
102
+ | DisconnectRequestMessage
103
+ | SignMessageRequestMessage
104
+ | SignTransactionRequestMessage
105
+ | GetAccountsRequestMessage
106
+ | GetConnectionStateRequestMessage
107
+ | GetSigningContextRequestMessage
108
+ | SelectAccountRequestMessage
109
+ | ManageAccountsRequestMessage;
110
+
111
+ export interface DisconnectResult {
112
+ // Empty object keeps compatibility with existing consumers expecting a success payload
113
+ }
114
+
115
+ export interface GetAccountsResult {
116
+ accounts: WalletAccount[];
117
+ }
118
+
119
+ export interface GetConnectionStateResult {
120
+ isAuthorized: boolean;
121
+ isConnected: boolean;
122
+ isUnlocked: boolean;
123
+ hasPasskey: boolean;
124
+ hasWalletAccount: boolean;
125
+ accounts: WalletAccount[];
126
+ selectedAccount: WalletAccount | null;
127
+ metadata: AppMetadata | null;
128
+ }
129
+
130
+ export interface SelectAccountPayload {
131
+ publicKey: string;
132
+ }
133
+
134
+ export interface SelectAccountResult {
135
+ account: WalletAccount;
136
+ }
137
+
138
+ export interface ManageAccountsResult {
139
+ accounts: WalletAccount[];
140
+ selectedAccount: WalletAccount | null;
141
+ }
142
+
143
+ type RequestResultMap = {
144
+ [POST_MESSAGE_REQUEST_TYPES.CONNECT]: ConnectResult;
145
+ [POST_MESSAGE_REQUEST_TYPES.DISCONNECT]: DisconnectResult;
146
+ [POST_MESSAGE_REQUEST_TYPES.SIGN_MESSAGE]: SignMessageResult;
147
+ [POST_MESSAGE_REQUEST_TYPES.SIGN_TRANSACTION]: SignTransactionResult;
148
+ [POST_MESSAGE_REQUEST_TYPES.GET_ACCOUNTS]: GetAccountsResult;
149
+ [POST_MESSAGE_REQUEST_TYPES.GET_CONNECTION_STATE]: GetConnectionStateResult;
150
+ [POST_MESSAGE_REQUEST_TYPES.GET_SIGNING_CONTEXT]: GetSigningContextResult;
151
+ [POST_MESSAGE_REQUEST_TYPES.SELECT_ACCOUNT]: SelectAccountResult;
152
+ [POST_MESSAGE_REQUEST_TYPES.MANAGE_ACCOUNTS]: ManageAccountsResult;
153
+ };
154
+
155
+ interface ResponseErrorPayload {
156
+ code: ErrorCode;
157
+ message: string;
158
+ data?: unknown;
159
+ }
160
+
161
+ type SuccessResponse<TType extends RequestType> = {
162
+ id: string;
163
+ success: true;
164
+ result: RequestResultMap[TType];
165
+ };
166
+
167
+ type ErrorResponse = {
168
+ id: string;
169
+ success: false;
170
+ error: ResponseErrorPayload;
171
+ };
172
+
173
+ export type PostMessageResponse<TType extends RequestType = RequestType> =
174
+ | SuccessResponse<TType>
175
+ | ErrorResponse;
176
+
177
+ export type SuccessfulPostMessageResponse<
178
+ TType extends RequestType = RequestType,
179
+ > = Extract<PostMessageResponse<TType>, { success: true }>;
180
+
181
+ export type InferPostMessageResponse<TRequest extends PostMessageRequest> =
182
+ PostMessageResponse<TRequest["type"]>;
183
+
184
+ export type InferSuccessfulPostMessageResponse<
185
+ TRequest extends PostMessageRequest,
186
+ > = SuccessfulPostMessageResponse<TRequest["type"]>;
187
+
188
+ export interface PostMessageEvent<
189
+ TEvent extends EmbeddedProviderEvent = EmbeddedProviderEvent,
190
+ TData = any,
191
+ > {
192
+ type: typeof POST_MESSAGE_EVENT_TYPE;
193
+ event: TEvent;
194
+ data?: TData;
195
+ }
196
+
197
+ export const ErrorCode = {
198
+ USER_REJECTED: "USER_REJECTED",
199
+ WALLET_LOCKED: "WALLET_LOCKED",
200
+ INVALID_PASSWORD: "INVALID_PASSWORD",
201
+ ALREADY_CONNECTED: "ALREADY_CONNECTED",
202
+ ACCOUNT_NOT_FOUND: "ACCOUNT_NOT_FOUND",
203
+ ACCOUNT_CHANGED: "ACCOUNT_CHANGED",
204
+ INVALID_TRANSACTION: "INVALID_TRANSACTION",
205
+ TRANSACTION_FAILED: "TRANSACTION_FAILED",
206
+ INSUFFICIENT_FUNDS: "INSUFFICIENT_FUNDS",
207
+ NETWORK_ERROR: "NETWORK_ERROR",
208
+ TIMEOUT: "TIMEOUT",
209
+ UNKNOWN_ERROR: "UNKNOWN_ERROR",
210
+ } as const;
211
+
212
+ export type ErrorCode = (typeof ErrorCode)[keyof typeof ErrorCode];
213
+
214
+ export type ConnectMetadataInput = Partial<AppMetadata>;
215
+
216
+ export type ConnectIntent = "default" | "switch-account";
217
+
218
+ export interface ConnectRequestPayload {
219
+ metadata?: ConnectMetadataInput;
220
+ preferredAccountAddress?: string;
221
+ intent?: ConnectIntent;
222
+ }
223
+
224
+ export type { AppMetadata, ConnectResult };
225
+
226
+ export interface SignMessagePayload {
227
+ message: string | number[];
228
+ accountIndex?: number;
229
+ }
230
+
231
+ export interface SignMessageResult {
232
+ signature: number[];
233
+ publicKey: string;
234
+ }
235
+
236
+ /**
237
+ * Wallet-managed instruction signing intent.
238
+ *
239
+ * Dapps provide the instruction data and account context. The wallet owns
240
+ * signing strategy details such as passkey validation, fee payer choice,
241
+ * account ordering, headers, nonces, and final wire layout. Review metadata
242
+ * is treated as untrusted display-only data.
243
+ */
244
+ export interface SignTransactionPayload {
245
+ walletAddress?: string;
246
+ programAddress: string;
247
+ instructionData: string;
248
+ readWriteAddresses?: string[];
249
+ readOnlyAddresses?: string[];
250
+ review?: TransactionReviewPayload;
251
+ }
252
+
253
+ export interface SignTransactionResult {
254
+ signedTransaction: string;
255
+ }
256
+
257
+ export interface TransactionReviewSimulation {
258
+ before?: string;
259
+ after?: string;
260
+ }
261
+
262
+ export interface TransactionReviewAbiReflection {
263
+ label?: string;
264
+ kind?: string | null;
265
+ typeName?: string;
266
+ value?: unknown;
267
+ rawHex?: string;
268
+ source?: string;
269
+ error?: string;
270
+ }
271
+
272
+ export interface TransactionReviewPayload {
273
+ appName?: string;
274
+ programAddress?: string;
275
+ abiName?: string;
276
+ instruction?: string;
277
+ simulation?: TransactionReviewSimulation;
278
+ abiReflection?: TransactionReviewAbiReflection;
279
+ }
280
+
281
+ export interface GetSigningContextResult {
282
+ signingContext: ThruSigningContext;
283
+ }
@@ -0,0 +1,12 @@
1
+ import { normalizeWalletAccountResult } from "../interfaces";
2
+ import type { GetConnectionStateResult } from "./postMessage";
3
+
4
+ export function normalizeConnectionStateResult(
5
+ result: GetConnectionStateResult,
6
+ ): GetConnectionStateResult {
7
+ if (!result.isAuthorized || !result.hasPasskey) {
8
+ return { ...result, accounts: [], selectedAccount: null };
9
+ }
10
+
11
+ return normalizeWalletAccountResult(result);
12
+ }