better-near-auth 1.3.0 → 1.4.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/dist/client.d.ts CHANGED
@@ -27,6 +27,8 @@ export interface SIWNClientActions {
27
27
  publicKey: string | null;
28
28
  networkId: string;
29
29
  } | null;
30
+ isWalletConnected: () => boolean;
31
+ ensureConnected: () => Promise<boolean>;
30
32
  disconnect: () => Promise<void>;
31
33
  link: (callbacks?: AuthCallbacks) => Promise<void>;
32
34
  unlink: (params: {
@@ -63,6 +65,7 @@ export interface SIWNClientPlugin extends BetterAuthClientPlugin {
63
65
  publicKey: string | null;
64
66
  networkId: string;
65
67
  } | null>>;
68
+ walletConnected: ReturnType<typeof atom<boolean>>;
66
69
  };
67
70
  getActions: ($fetch: BetterFetch, $store: ClientStore, options: BetterAuthClientOptions | undefined) => SIWNClientActions;
68
71
  }
@@ -1 +1 @@
1
- {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.d.ts","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/dist/client.js CHANGED
@@ -5,12 +5,11 @@ import { atom } from "nanostores";
5
5
  import {} from "./types.js";
6
6
  export const siwnClient = (config) => {
7
7
  const nearState = atom(null);
8
+ const walletConnected = atom(false);
8
9
  const network = config.networkId || "mainnet";
9
- const connector = new NearConnector({ network });
10
- const near = new Near({
11
- network,
12
- wallet: fromNearConnect(connector),
13
- });
10
+ let connector = null;
11
+ let near = null;
12
+ let clientInitialized = false;
14
13
  const handleAccountConnection = async (accountId, publicKey) => {
15
14
  if (!accountId)
16
15
  return;
@@ -19,44 +18,134 @@ export const siwnClient = (config) => {
19
18
  publicKey: publicKey || null,
20
19
  networkId: network,
21
20
  });
21
+ walletConnected.set(true);
22
22
  };
23
- connector.on("wallet:signIn", async (data) => {
24
- const accountId = data.accounts?.[0]?.accountId;
25
- const publicKey = data.accounts?.[0]?.publicKey;
26
- if (accountId) {
27
- await handleAccountConnection(accountId, publicKey);
23
+ const initClient = ($fetch) => {
24
+ if (clientInitialized)
25
+ return true;
26
+ if (typeof globalThis.window === "undefined")
27
+ return false;
28
+ connector = new NearConnector({ network });
29
+ near = new Near({
30
+ network,
31
+ wallet: fromNearConnect(connector),
32
+ });
33
+ connector.on("wallet:signIn", async (data) => {
34
+ const accountId = data.accounts?.[0]?.accountId;
35
+ const publicKey = data.accounts?.[0]?.publicKey;
36
+ if (accountId) {
37
+ await handleAccountConnection(accountId, publicKey);
38
+ }
39
+ });
40
+ connector.on("wallet:signOut", () => {
41
+ walletConnected.set(false);
42
+ const state = nearState.get();
43
+ if (state) {
44
+ nearState.set({ accountId: state.accountId, publicKey: null, networkId: state.networkId });
45
+ }
46
+ });
47
+ connector.getConnectedWallet().then(({ accounts }) => {
48
+ const account = accounts?.[0];
49
+ if (account?.accountId && !nearState.get()) {
50
+ nearState.set({
51
+ accountId: account.accountId,
52
+ publicKey: account.publicKey ?? null,
53
+ networkId: network,
54
+ });
55
+ }
56
+ if (account?.accountId) {
57
+ walletConnected.set(true);
58
+ }
59
+ }).catch(() => { });
60
+ if ($fetch) {
61
+ restoreFromSession($fetch);
28
62
  }
29
- });
30
- connector.on("wallet:signOut", () => {
31
- nearState.set(null);
32
- });
33
- connector.getConnectedWallet().then(({ accounts }) => {
34
- const account = accounts?.[0];
35
- if (account?.accountId && !nearState.get()) {
36
- nearState.set({
37
- accountId: account.accountId,
38
- publicKey: account.publicKey ?? null,
39
- networkId: network,
40
- });
63
+ clientInitialized = true;
64
+ return true;
65
+ };
66
+ let sessionRestored = false;
67
+ const restoreFromSession = async ($fetch) => {
68
+ if (sessionRestored)
69
+ return;
70
+ const state = nearState.get();
71
+ if (state?.accountId) {
72
+ sessionRestored = true;
73
+ return;
41
74
  }
42
- }).catch(() => { });
75
+ try {
76
+ const res = await $fetch("/near/list-accounts", { method: "GET" });
77
+ const accounts = res.data?.accounts;
78
+ if (accounts?.length) {
79
+ const primary = accounts.find((a) => a.isPrimary) || accounts[0];
80
+ if (primary) {
81
+ nearState.set({
82
+ accountId: primary.accountId,
83
+ publicKey: primary.publicKey ?? null,
84
+ networkId: primary.network,
85
+ });
86
+ }
87
+ }
88
+ }
89
+ catch { }
90
+ sessionRestored = true;
91
+ };
92
+ const requireConnector = () => {
93
+ if (!connector)
94
+ throw new Error("Wallet not initialized — this operation requires a browser environment");
95
+ return connector;
96
+ };
97
+ const requireNear = () => {
98
+ if (!near)
99
+ throw new Error("Wallet not initialized — this operation requires a browser environment");
100
+ return near;
101
+ };
102
+ const ensureWalletConnected = async () => {
103
+ const conn = requireConnector();
104
+ if (walletConnected.get()) {
105
+ try {
106
+ const { accounts } = await conn.getConnectedWallet();
107
+ if (accounts?.length)
108
+ return true;
109
+ }
110
+ catch { }
111
+ }
112
+ return new Promise((resolve) => {
113
+ const signInHandler = (data) => {
114
+ const accountId = data.accounts?.[0]?.accountId;
115
+ const publicKey = data.accounts?.[0]?.publicKey;
116
+ if (accountId) {
117
+ handleAccountConnection(accountId, publicKey);
118
+ resolve(true);
119
+ }
120
+ };
121
+ conn.on("wallet:signIn", signInHandler);
122
+ conn.connect().catch(() => { }).finally(() => {
123
+ conn.off("wallet:signIn", signInHandler);
124
+ if (!walletConnected.get()) {
125
+ resolve(false);
126
+ }
127
+ });
128
+ });
129
+ };
43
130
  const signWithWallet = async () => {
131
+ const conn = requireConnector();
132
+ const nearClient = requireNear();
44
133
  const nonceBytes = generateNonce();
45
134
  const nonceHex = hex.encode(nonceBytes);
46
135
  const message = `Sign in to ${config.recipient}`;
47
136
  let connectedWallet = null;
48
137
  try {
49
- connectedWallet = await connector.getConnectedWallet();
138
+ connectedWallet = await conn.getConnectedWallet();
50
139
  }
51
140
  catch { }
52
141
  if (connectedWallet?.accounts?.length) {
53
- const signedMessage = await near.signMessage({
142
+ const signedMessage = await nearClient.signMessage({
54
143
  message,
55
144
  recipient: config.recipient,
56
145
  nonce: nonceBytes,
57
146
  });
58
147
  if (!signedMessage?.accountId) {
59
- throw new Error("Wallet not connected");
148
+ throw new Error("Wallet sign-in was cancelled or failed");
60
149
  }
61
150
  return {
62
151
  signedMessage,
@@ -76,9 +165,9 @@ export const siwnClient = (config) => {
76
165
  };
77
166
  }
78
167
  };
79
- connector.on("wallet:signInAndSignMessage", handler);
168
+ conn.on("wallet:signInAndSignMessage", handler);
80
169
  try {
81
- await connector.connect({
170
+ await conn.connect({
82
171
  signMessageParams: {
83
172
  message,
84
173
  recipient: config.recipient,
@@ -87,10 +176,10 @@ export const siwnClient = (config) => {
87
176
  });
88
177
  }
89
178
  finally {
90
- connector.off("wallet:signInAndSignMessage", handler);
179
+ conn.off("wallet:signInAndSignMessage", handler);
91
180
  }
92
181
  if (!result.value) {
93
- throw new Error("Wallet not connected");
182
+ throw new Error("Wallet sign-in was cancelled or failed");
94
183
  }
95
184
  return {
96
185
  signedMessage: result.value.signedMessage,
@@ -102,9 +191,16 @@ export const siwnClient = (config) => {
102
191
  const buildSignedDelegateActionInternal = async (receiverId, buildActions) => {
103
192
  const state = nearState.get();
104
193
  if (!state?.accountId) {
105
- throw new Error("No wallet connectedcannot sign delegate action");
194
+ throw new Error("No NEAR account found please sign in with your NEAR wallet");
195
+ }
196
+ if (!walletConnected.get()) {
197
+ const reconnected = await ensureWalletConnected();
198
+ if (!reconnected) {
199
+ throw new Error("Wallet connection required — please approve the connection to sign");
200
+ }
106
201
  }
107
- const builder = buildActions(near.transaction(state.accountId), receiverId);
202
+ const nearClient = requireNear();
203
+ const builder = buildActions(nearClient.transaction(state.accountId), receiverId);
108
204
  const { payload } = await builder.delegate();
109
205
  return payload;
110
206
  };
@@ -113,8 +209,10 @@ export const siwnClient = (config) => {
113
209
  $InferServerPlugin: {},
114
210
  getAtoms: (_$fetch) => ({
115
211
  nearState,
212
+ walletConnected,
116
213
  }),
117
214
  getActions: ($fetch, _$store, _options) => {
215
+ initClient($fetch);
118
216
  return {
119
217
  near: {
120
218
  nonce: async (params, fetchOptions) => {
@@ -150,8 +248,28 @@ export const siwnClient = (config) => {
150
248
  return state?.accountId || null;
151
249
  },
152
250
  getState: () => nearState.get(),
251
+ isWalletConnected: () => walletConnected.get(),
252
+ ensureConnected: async () => {
253
+ if (!clientInitialized) {
254
+ if (!initClient())
255
+ return false;
256
+ }
257
+ if (walletConnected.get()) {
258
+ try {
259
+ const { accounts } = await requireConnector().getConnectedWallet();
260
+ if (accounts?.length)
261
+ return true;
262
+ }
263
+ catch (err) {
264
+ console.error("[siwn] restoreFromSession failed:", err instanceof Error ? err.message : err);
265
+ }
266
+ }
267
+ return ensureWalletConnected();
268
+ },
153
269
  disconnect: async () => {
154
- await connector.disconnect();
270
+ if (connector)
271
+ await connector.disconnect();
272
+ walletConnected.set(false);
155
273
  nearState.set(null);
156
274
  },
157
275
  link: async (callbacks) => {
@@ -216,7 +334,11 @@ export const siwnClient = (config) => {
216
334
  method: "GET",
217
335
  });
218
336
  },
219
- client: near,
337
+ get client() {
338
+ if (!near)
339
+ throw new Error("Wallet not initialized — this operation requires a browser environment");
340
+ return near;
341
+ },
220
342
  },
221
343
  signIn: {
222
344
  near: async (callbacks) => {
@@ -1 +1 @@
1
- {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-near-auth",
3
- "version": "1.3.0",
3
+ "version": "1.4.0",
4
4
  "description": "Sign in with NEAR (SIWN) plugin for Better Auth",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.js",
@@ -8,7 +8,7 @@ description: >
8
8
  using authClient.near.* methods, or building delegate actions for gasless relay.
9
9
  type: core
10
10
  library: better-near-auth
11
- library_version: "1.1.0"
11
+ library_version: "1.2.1"
12
12
  sources:
13
13
  - "elliotBraem/better-near-auth:src/client.ts"
14
14
  - "elliotBraem/better-near-auth:src/types.ts"
@@ -20,8 +20,21 @@ sources:
20
20
 
21
21
  Client-side plugin for NEAR wallet authentication and gasless relay. Connects to NEAR wallets via NearConnect, provides `authClient.near.*` actions for sign-in, account management, profile lookup, and delegate action building.
22
22
 
23
+ ## SSR Behavior
24
+
25
+ `siwnClient()` is SSR-safe. Wallet resources (`NearConnector`, `Near`, event listeners) are lazily initialized on first client-side access — they do not run at construction time. On the server:
26
+
27
+ - `getAccountId()` returns `null` (no session restore yet)
28
+ - `getState()` returns `null`
29
+ - `isWalletConnected()` returns `false`
30
+ - `buildSignedDelegateAction`, `signWithWallet`, `ensureConnected` throw "Wallet not initialized — this operation requires a browser environment"
31
+ - `near.client` getter throws on access
32
+ - HTTP-only methods (`nonce`, `verify`, `view`, `relayTransaction`, etc.) work normally via `$fetch`
33
+
23
34
  ## Setup
24
35
 
36
+ ### Simple app (module singleton)
37
+
25
38
  ```typescript
26
39
  import { createAuthClient } from "better-auth/client";
27
40
  import { siwnClient } from "better-near-auth/client";
@@ -36,6 +49,36 @@ export const authClient = createAuthClient({
36
49
  });
37
50
  ```
38
51
 
52
+ ### SSR app (router context)
53
+
54
+ For TanStack Router with server rendering, create the auth client once in your router setup and access via context:
55
+
56
+ ```typescript
57
+ // auth.ts
58
+ import { createAuthClient as createBetterAuthClient } from "better-auth/react";
59
+ import { siwnClient } from "better-near-auth/client";
60
+ import { useRouter } from "@tanstack/react-router";
61
+
62
+ export function createAuthClient() {
63
+ return createBetterAuthClient({
64
+ plugins: [siwnClient({ recipient: getAccount(), networkId: getNetworkId() })],
65
+ });
66
+ }
67
+
68
+ export type AuthClient = ReturnType<typeof createAuthClient>;
69
+
70
+ export function useAuthClient(): AuthClient {
71
+ return useRouter().options.context.authClient;
72
+ }
73
+
74
+ // hydrate.tsx — create once, put in router context
75
+ const { router } = createRouter({
76
+ context: { authClient: createAuthClient() },
77
+ });
78
+ ```
79
+
80
+ A module-level singleton is shared across SSR requests, causing data leaks. Router context gives one client per request on server, one per app on client.
81
+
39
82
  The `recipient` must match the server's `siwn()` recipient exactly. `networkId` defaults to `"mainnet"`.
40
83
 
41
84
  ## Core Patterns
@@ -77,12 +120,36 @@ console.log("Status:", status.data.status);
77
120
 
78
121
  The `buildSignedDelegateAction` callback receives a `TransactionBuilder` from near-kit and the `receiverId`. Use `builder.functionCall()` to construct actions. The builder calls `.delegate()` internally and returns a base64 payload string.
79
122
 
123
+ `buildSignedDelegateAction` automatically calls `ensureConnected()` if the wallet is disconnected, prompting the user to reconnect.
124
+
125
+ ### Direct send (user pays gas)
126
+
127
+ ```typescript
128
+ // Must ensure wallet is connected before .send()
129
+ await authClient.near.ensureConnected();
130
+ return authClient.near.client
131
+ .transaction(accountId)
132
+ .functionCall(contractId, "method", args, {
133
+ gas: Gas.Tgas(30),
134
+ attachedDeposit: BigInt(0),
135
+ })
136
+ .send({ waitUntil: "FINAL" });
137
+ ```
138
+
139
+ Wallet extensions (Meteor, HERE) may disconnect after the initial sign-in popup. Always call `ensureConnected()` before `.send()` — it opens a reconnection prompt if needed. `buildSignedDelegateAction` does this automatically, but direct `.send()` does not.
140
+
80
141
  ### Wallet state and profile management
81
142
 
82
143
  ```typescript
83
- // Get current account
144
+ // Get current account (persists across wallet disconnects)
84
145
  const accountId = authClient.near.getAccountId(); // string | null
85
146
 
147
+ // Check if signing operations are available
148
+ const canSign = authClient.near.isWalletConnected(); // boolean
149
+
150
+ // Prompt wallet reconnection if disconnected
151
+ const connected = await authClient.near.ensureConnected(); // Promise<boolean>
152
+
86
153
  // Get full wallet state
87
154
  const state = authClient.near.getState(); // { accountId, publicKey, networkId } | null
88
155
 
@@ -94,6 +161,8 @@ const aliceProfile = await authClient.near.getProfile("alice.near");
94
161
  await authClient.near.disconnect();
95
162
  ```
96
163
 
164
+ When the wallet disconnects externally (user signs out from wallet UI), `nearState` preserves `accountId` but clears `publicKey`. Use `isWalletConnected()` to check if signing operations are available, and `getAccountId()` for display purposes (works even when disconnected).
165
+
97
166
  ### Account linking and contract view calls
98
167
 
99
168
  ```typescript
@@ -127,8 +196,10 @@ const result = await authClient.near.view({
127
196
  | `verify(params)` | `Promise<Response<VerifyResponse>>` | Verify NEP-413 signature |
128
197
  | `getProfile(accountId?)` | `Promise<Response<Profile>>` | Get NEAR profile |
129
198
  | `view(params)` | `Promise<Response<ViewResponse>>` | Server-side contract view call |
130
- | `getAccountId()` | `string \| null` | Currently connected account ID |
199
+ | `getAccountId()` | `string \| null` | Currently connected account ID (persists across disconnects) |
131
200
  | `getState()` | `{ accountId, publicKey, networkId } \| null` | Wallet state |
201
+ | `isWalletConnected()` | `boolean` | Whether wallet is actively connected |
202
+ | `ensureConnected()` | `Promise<boolean>` | Reconnect wallet if disconnected |
132
203
  | `disconnect()` | `Promise<void>` | Disconnect wallet |
133
204
  | `link(callbacks?)` | `Promise<void>` | Link NEAR account to session |
134
205
  | `unlink(params)` | `Promise<Response>` | Unlink NEAR account |
@@ -138,7 +209,7 @@ const result = await authClient.near.view({
138
209
  | `getRelayStatus(txHash)` | `Promise<Response<RelayStatusResponse>>` | Check relayed tx status |
139
210
  | `getRelayerInfo()` | `Promise<Response<RelayerInfo>>` | Get relayer info and balance |
140
211
  | `relayHistory()` | `Promise<Response<RelayHistoryResponse>>` | List relayed transactions |
141
- | `client` | `Near` | Access near-kit Near instance directly |
212
+ | `client` | `Near` | Access near-kit Near instance (throws on server) |
142
213
 
143
214
  ### authClient.signIn
144
215
 
@@ -157,6 +228,41 @@ interface AuthCallbacks {
157
228
 
158
229
  ## Common Mistakes
159
230
 
231
+ ### CRITICAL Creating multiple siwnClient instances
232
+
233
+ Wrong:
234
+
235
+ ```typescript
236
+ // Factory that creates new client each call
237
+ function getAuthClient(config) {
238
+ return createAuthClient({
239
+ plugins: [siwnClient({ recipient: getAccount(config) })],
240
+ });
241
+ }
242
+ // Each call = new nearState atom = wallet state lost
243
+ ```
244
+
245
+ Correct:
246
+
247
+ ```typescript
248
+ // Single module-level instance (simple apps)
249
+ export const authClient = createAuthClient({
250
+ plugins: [siwnClient({ recipient: "myapp.near" })],
251
+ });
252
+
253
+ // OR: router context singleton (SSR apps)
254
+ export function createAuthClient() {
255
+ return createBetterAuthClient({
256
+ plugins: [siwnClient({ recipient: getAccount() })],
257
+ });
258
+ }
259
+ // Create once in router setup, access via context
260
+ ```
261
+
262
+ `siwnClient()` creates stateful singletons: a `nearState` atom, a `walletConnected` atom, a `NearConnector` with event listeners, and a `Near` instance. Multiple instances means wallet sign-in populates one atom while your app reads from another. Always create exactly one `siwnClient()` per app lifecycle.
263
+
264
+ Source: src/client.ts:64-72
265
+
160
266
  ### CRITICAL Recipient mismatch between server and client
161
267
 
162
268
  Wrong:
@@ -181,39 +287,32 @@ siwnClient({ recipient: "myapp.com" });
181
287
 
182
288
  The client embeds the recipient in the signed message. The server verifies against its own recipient. A mismatch causes the verify endpoint to reject the signature with "Unauthorized: Invalid signature" — which is confusing because the signature is valid, just for a different recipient.
183
289
 
184
- Source: src/client.ts:17, src/index.ts:225
290
+ Source: src/client.ts:108, src/index.ts:225
185
291
 
186
292
  See also: siwn/SKILL.md — server plugin recipient configuration
187
293
 
188
- ### HIGH Calling buildSignedDelegateAction without connected wallet
294
+ ### HIGH Using near.client.send() without ensuring wallet connection
189
295
 
190
296
  Wrong:
191
297
 
192
298
  ```typescript
193
- // No wallet connected yet
194
- const payload = await authClient.near.buildSignedDelegateAction(
195
- "myapp.near",
196
- (builder, receiverId) => builder.functionCall(receiverId, "method", {})
197
- );
299
+ authClient.near.client.transaction(accountId)
300
+ .functionCall(contract, "method", args, opts)
301
+ .send(); // fails if wallet disconnected after sign-in
198
302
  ```
199
303
 
200
304
  Correct:
201
305
 
202
306
  ```typescript
203
- // Check wallet state before building delegate action
204
- const accountId = authClient.near.getAccountId();
205
- if (!accountId) {
206
- await authClient.signIn.near();
207
- }
208
- const payload = await authClient.near.buildSignedDelegateAction(
209
- "myapp.near",
210
- (builder, receiverId) => builder.functionCall(receiverId, "method", {})
211
- );
307
+ await authClient.near.ensureConnected(); // reconnects wallet if needed
308
+ authClient.near.client.transaction(accountId)
309
+ .functionCall(contract, "method", args, opts)
310
+ .send();
212
311
  ```
213
312
 
214
- `buildSignedDelegateAction` reads `accountId` from the `nearState` atom. If the wallet is not connected, nearState is null and the function throws "No wallet connected cannot sign delegate action" with no user-facing prompt to connect.
313
+ Wallet extensions (Meteor, HERE) may disconnect after the initial sign-in popup. `ensureConnected()` opens a reconnection prompt if needed. `buildSignedDelegateAction` calls this automatically, but direct `.send()` does not.
215
314
 
216
- Source: src/client.ts:176-179
315
+ Source: src/client.ts:249-253, src/client.ts:310-317
217
316
 
218
317
  ### HIGH Constructing transactions with wrong builder pattern
219
318
 
@@ -242,7 +341,7 @@ const result = await authClient.near.relayTransaction({ payload });
242
341
 
243
342
  Delegate actions must be built through `buildSignedDelegateAction`, which uses near-kit's `TransactionBuilder.delegate()` method. Direct `.send()` broadcasts from the client account and requires the user to pay gas — defeating the gasless relay purpose.
244
343
 
245
- Source: src/client.ts:172-185, maintainer interview
344
+ Source: src/client.ts:240-260
246
345
 
247
346
  See also: relay/SKILL.md — relay endpoint validation and whitelisting
248
347
 
@@ -273,7 +372,7 @@ await authClient.signIn.near({
273
372
 
274
373
  `signIn.near()` handles wallet connection, NEP-413 message signing, nonce management, and server verification in a single call. Calling `verify` directly requires manually constructing all parameters and does not handle wallet connection.
275
374
 
276
- Source: src/client.ts:314-348
375
+ Source: src/client.ts:402-437
277
376
 
278
377
  ### MEDIUM Not subscribing to wallet disconnect events
279
378
 
@@ -291,11 +390,13 @@ Correct:
291
390
  import { useStore } from "nanostores/react";
292
391
  const { nearState } = authClient.$store;
293
392
  const state = useStore(nearState);
294
- // state is null when wallet disconnects externally
295
- ```
393
+ // state preserves accountId when wallet disconnects
394
+ // publicKey becomes null, walletConnected becomes false
296
395
 
297
- When the wallet disconnects externally (user signs out from wallet UI), the `nearState` atom is set to null. UI components that only read `getAccountId()` once will show stale account info.
396
+ // Or check signing availability:
397
+ const canSign = authClient.near.isWalletConnected();
398
+ ```
298
399
 
299
- Source: src/client.ts:62,82-92
400
+ When the wallet disconnects externally (user signs out from wallet UI), `nearState` preserves `accountId` but clears `publicKey` and sets `walletConnected` to false. Use `isWalletConnected()` to check if signing operations are available, and `getAccountId()` for display purposes (works even when disconnected).
300
401
 
301
- See also: siwn/SKILL.md — server-side nonce and verify endpoints
402
+ Source: src/client.ts:65-66, src/client.ts:102-108
@@ -8,7 +8,7 @@ description: >
8
8
  configuring RotatingKeyStore for high-throughput relay.
9
9
  type: core
10
10
  library: better-near-auth
11
- library_version: "1.1.0"
11
+ library_version: "1.2.1"
12
12
  sources:
13
13
  - "elliotBraem/better-near-auth:src/index.ts"
14
14
  - "elliotBraem/better-near-auth:src/utils.ts"
@@ -189,7 +189,7 @@ siwn({
189
189
  // Send NEAR to that account ID to fund the relayer
190
190
  ```
191
191
 
192
- The ephemeral mode generates an implicit account (hex of public key) with zero balance. Without funding, every relay attempt fails with an insufficient balance error from the NEAR RPC. Alternatively, use explicit mode with a pre-funded named account.
192
+ The ephemeral mode generates an implicit account (hex of public key) with zero balance. Without funding, every relay attempt fails with an insufficient balance error from the NEAR RPC. The server catches this at src/index.ts:952-958 and surfaces it as `"Relay failed"` — check server logs for the actual RPC error. Alternatively, use explicit mode with a pre-funded named account.
193
193
 
194
194
  Source: src/index.ts:179-181, maintainer interview
195
195
 
@@ -250,7 +250,7 @@ const payload = await authClient.near.buildSignedDelegateAction(
250
250
  const result = await authClient.near.relayTransaction({ payload });
251
251
  ```
252
252
 
253
- Delegate actions must be built using the near-kit `TransactionBuilder` with `.delegate()`, not `.send()` directly. The wallet signs a delegate action; the relayer submits it on-chain. External code should construct the transaction object using the builder API, not attempt to broadcast directly.
253
+ Delegate actions must be built using the near-kit `TransactionBuilder` with `.delegate()`, not `.send()` directly. The wallet signs a delegate action; the relayer submits it on-chain. For direct sends (user pays gas), call `authClient.near.ensureConnected()` first wallet extensions may disconnect between sign-in and signing.
254
254
 
255
255
  Source: src/client.ts:172-185, maintainer interview
256
256
 
@@ -8,7 +8,7 @@ description: >
8
8
  or debugging NEP-413 verify or nonce issues.
9
9
  type: core
10
10
  library: better-near-auth
11
- library_version: "1.1.0"
11
+ library_version: "1.2.1"
12
12
  sources:
13
13
  - "elliotBraem/better-near-auth:src/index.ts"
14
14
  - "elliotBraem/better-near-auth:src/profile.ts"
@@ -0,0 +1,356 @@
1
+ ---
2
+ name: tanstack
3
+ description: >
4
+ Integrate better-near-auth with TanStack Router (SSR or CSR). Set up auth
5
+ client as a router context singleton, useAuthClient hook, session query
6
+ options, inferred types from AuthClient, and ensureConnected before signing.
7
+ Load when scaffolding a new TanStack Router app with better-near-auth,
8
+ wiring auth into router context, or debugging wallet state loss after
9
+ sign-in in SSR/CSR TanStack apps.
10
+ type: framework
11
+ library: better-near-auth
12
+ library_version: "1.2.1"
13
+ sources:
14
+ - "elliotBraem/better-near-auth:src/client.ts"
15
+ - "elliotBraem/better-near-auth:examples/auth.everything.dev/ui/src/auth.ts"
16
+ - "elliotBraem/better-near-auth:examples/auth.everything.dev/ui/src/app.ts"
17
+ - "elliotBraem/better-near-auth:examples/auth.everything.dev/ui/src/hydrate.tsx"
18
+ - "elliotBraem/better-near-auth:examples/auth.everything.dev/ui/src/router.tsx"
19
+ - "elliotBraem/better-near-auth:examples/auth.everything.dev/ui/src/router.server.tsx"
20
+ - "elliotBraem/better-near-auth:examples/browser-2-server/apps/web/src/lib/auth-client.ts"
21
+ ---
22
+
23
+ # Better-Near-Auth — TanStack Router Integration
24
+
25
+ Integration pattern for better-near-auth with TanStack Router apps, covering both CSR (client-side only) and SSR (server-rendered) setups. Establishes the auth client as a router context singleton, provides hooks and query options, and ensures wallet state survives page navigation and hydration.
26
+
27
+ ## Architecture: Two Patterns
28
+
29
+ ### Pattern A: Module singleton (CSR only)
30
+
31
+ For apps without SSR — config is known at build time or from env vars:
32
+
33
+ ```typescript
34
+ // lib/auth-client.ts
35
+ import { createAuthClient } from "better-auth/react";
36
+ import { siwnClient } from "better-near-auth/client";
37
+
38
+ export const authClient = createAuthClient({
39
+ baseURL: import.meta.env.VITE_SERVER_URL || "http://localhost:3000",
40
+ plugins: [
41
+ siwnClient({ recipient: "myapp.near", networkId: "mainnet" }),
42
+ ],
43
+ });
44
+ ```
45
+
46
+ Import directly in any component or route. Simple, correct for CSR.
47
+
48
+ ### Pattern B: Router context singleton (SSR or CSR with runtime config)
49
+
50
+ For TanStack Router apps with SSR, Module Federation, or runtime config (`window.__RUNTIME_CONFIG__`):
51
+
52
+ ```typescript
53
+ // auth.ts — single file for client factory, types, hooks, and query options
54
+ import { createAuthClient as createBetterAuthClient } from "better-auth/react";
55
+ import { siwnClient } from "better-near-auth/client";
56
+ import { useRouter } from "@tanstack/react-router";
57
+ import { useQuery } from "@tanstack/react-query";
58
+ import type { Auth } from "./auth-types.gen";
59
+ import { getAccount, getHostUrl, getNetworkId } from "@/app";
60
+
61
+ export function createAuthClient() {
62
+ return createBetterAuthClient({
63
+ baseURL: getHostUrl(),
64
+ fetchOptions: { credentials: "include" },
65
+ plugins: [
66
+ siwnClient({ recipient: getAccount(), networkId: getNetworkId() }),
67
+ ],
68
+ });
69
+ }
70
+
71
+ export type AuthClient = ReturnType<typeof createAuthClient>;
72
+ export type SessionData = AuthClient["$Infer"]["Session"];
73
+
74
+ export function useAuthClient(): AuthClient {
75
+ return useRouter().options.context.authClient;
76
+ }
77
+ ```
78
+
79
+ The auth client is created once in the router setup (not per component call) and accessed via context:
80
+
81
+ ```typescript
82
+ // hydrate.tsx
83
+ import { createAuthClient } from "./auth";
84
+
85
+ const { router } = createRouter({
86
+ context: {
87
+ authClient: createAuthClient(),
88
+ },
89
+ });
90
+
91
+ // router.server.tsx — same pattern
92
+ context: {
93
+ authClient: createAuthClient(),
94
+ }
95
+ ```
96
+
97
+ ## Type Inference from AuthClient
98
+
99
+ Don't manually define `Organization`, `Passkey`, or other entity types. Infer them from the client's API responses:
100
+
101
+ ```typescript
102
+ type UnwrapListResponse<T> = T extends (...args: any[]) => Promise<{
103
+ data: (infer U)[] | null; error: any
104
+ }> ? U : never;
105
+
106
+ export type Organization = UnwrapListResponse<AuthClient["organization"]["list"]>;
107
+ export type Passkey = UnwrapListResponse<AuthClient["passkey"]["listUserPasskeys"]>;
108
+ ```
109
+
110
+ This automatically includes any additional fields the server configured. Single source of truth: the `AuthClient` type, which is itself derived from the plugin list.
111
+
112
+ ## Session Query Options
113
+
114
+ Always pass the auth client directly — never thread `runtimeConfig` through query options:
115
+
116
+ ```typescript
117
+ export function sessionQueryOptions(
118
+ authClient: AuthClient,
119
+ initialSession?: SessionData | null,
120
+ ) {
121
+ return {
122
+ queryKey: ["session"],
123
+ queryFn: async () => {
124
+ const { data: session } = await authClient.getSession();
125
+ return session ?? null;
126
+ },
127
+ staleTime: 60 * 1000,
128
+ gcTime: 10 * 60 * 1000,
129
+ initialData: initialSession,
130
+ };
131
+ }
132
+ ```
133
+
134
+ In `beforeLoad`/`loader` (not components), use `context.authClient`:
135
+
136
+ ```typescript
137
+ beforeLoad: async ({ context }) => {
138
+ const session = await context.queryClient.ensureQueryData(
139
+ sessionQueryOptions(context.authClient, context.session),
140
+ );
141
+ if (!session?.user) {
142
+ throw redirect({ to: "/login" });
143
+ }
144
+ return { session };
145
+ },
146
+ ```
147
+
148
+ In components, use `useAuthClient()`:
149
+
150
+ ```typescript
151
+ const auth = useAuthClient();
152
+ const { data } = await auth.organization.list();
153
+ ```
154
+
155
+ ## Router Context Setup
156
+
157
+ ### Define RouterContext with authClient
158
+
159
+ ```typescript
160
+ // app.ts
161
+ import type { AuthClient, SessionData } from "./auth";
162
+
163
+ export interface RouterContext extends BaseRouterContext {
164
+ apiClient: ApiClient;
165
+ authClient: AuthClient;
166
+ }
167
+ ```
168
+
169
+ ### Wire in router files
170
+
171
+ Both `router.tsx` (client) and `router.server.tsx` (server) must include `authClient` in context:
172
+
173
+ ```typescript
174
+ context: {
175
+ queryClient,
176
+ authClient: opts.context.authClient,
177
+ apiClient: opts.context.apiClient,
178
+ runtimeConfig: opts.context.runtimeConfig,
179
+ session: opts.context.session,
180
+ },
181
+ ```
182
+
183
+ ### Remove runtimeConfig from component props
184
+
185
+ Components no longer need `runtimeConfig` props for auth. They use `useAuthClient()` instead. Remove `runtimeConfig` prop threading from:
186
+ - Route components that pass it to child components
187
+ - Shared components like `UserNav`, `OrgSwitcher`, `RelayFeed`, `NearProfile`
188
+
189
+ ## Wallet State and Signing
190
+
191
+ ### ensureConnected before signing
192
+
193
+ Wallet extensions (Meteor, HERE) may disconnect after the initial sign-in popup. Always call `ensureConnected()` before any signing operation:
194
+
195
+ ```typescript
196
+ // Relay mode — automatic (buildSignedDelegateAction calls ensureConnected internally)
197
+ const payload = await authClient.near.buildSignedDelegateAction(...);
198
+
199
+ // Direct mode — manual
200
+ await authClient.near.ensureConnected();
201
+ authClient.near.client.transaction(accountId)
202
+ .functionCall(contract, "method", args, opts)
203
+ .send({ waitUntil: "FINAL" });
204
+ ```
205
+
206
+ ### nearState persists accountId across disconnects
207
+
208
+ When the wallet disconnects externally:
209
+ - `getAccountId()` still returns the accountId (from session restore)
210
+ - `isWalletConnected()` returns false
211
+ - `publicKey` is cleared from state
212
+
213
+ This means UI can display the user's NEAR account even when the wallet is disconnected. Signing operations automatically prompt reconnection.
214
+
215
+ ## SSR Safety
216
+
217
+ `siwnClient()` is SSR-safe — wallet resources are lazily initialized on first client-side access. On the server they sit dormant. This means `createAuthClient()` can safely run in `router.server.tsx` without accessing browser APIs.
218
+
219
+ Methods that work on server (via `$fetch` only): `nonce`, `verify`, `view`, `relayTransaction`, `getRelayStatus`, `getRelayerInfo`, `relayHistory`, `getProfile`, `listAccounts`.
220
+
221
+ Methods that throw on server: `buildSignedDelegateAction`, `ensureConnected`, `signIn.near`, `link`, `disconnect`.
222
+
223
+ Properties that return defaults on server: `getAccountId()` → `null`, `getState()` → `null`, `isWalletConnected()` → `false`.
224
+
225
+ ## File Consolidation
226
+
227
+ Replace three separate files with one `auth.ts`:
228
+
229
+ | Before | After |
230
+ | ------ | ----- |
231
+ | `lib/auth-client.ts` (factory + types) | `auth.ts` (factory + types + hooks + queries) |
232
+ | `lib/session.ts` (query options) | `auth.ts` |
233
+ | `lib/auth-hooks.ts` (relay history hook) | `auth.ts` |
234
+
235
+ The consolidated `auth.ts` is ~80 lines and eliminates all `runtimeConfig` parameter threading.
236
+
237
+ ## Common Mistakes
238
+
239
+ ### CRITICAL Creating multiple siwnClient instances via factory
240
+
241
+ Wrong:
242
+
243
+ ```typescript
244
+ function getAuthClient(config) {
245
+ return createAuthClient({
246
+ plugins: [siwnClient({ recipient: getAccount(config) })],
247
+ });
248
+ }
249
+ // Every call creates new nearState atom — wallet state lost
250
+ ```
251
+
252
+ Correct:
253
+
254
+ ```typescript
255
+ // Module singleton (CSR)
256
+ export const authClient = createAuthClient({
257
+ plugins: [siwnClient({ recipient: "myapp.near" })],
258
+ });
259
+
260
+ // OR: Router context singleton (SSR)
261
+ export function createAuthClient() {
262
+ return createBetterAuthClient({
263
+ plugins: [siwnClient({ recipient: getAccount() })],
264
+ });
265
+ }
266
+ // Create once in router setup, access via useAuthClient()
267
+ ```
268
+
269
+ `siwnClient()` creates stateful singletons: `nearState` atom, `walletConnected` atom, `NearConnector` with event listeners, `Near` instance. Multiple instances means wallet sign-in populates one atom while your app reads from another. Always create exactly one per app lifecycle.
270
+
271
+ Source: src/client.ts:64-72
272
+
273
+ See also: client/SKILL.md — CRITICAL singleton requirement
274
+
275
+ ### HIGH Threading runtimeConfig through query options and component props
276
+
277
+ Wrong:
278
+
279
+ ```typescript
280
+ // session.ts
281
+ export const sessionQueryOptions = (initialSession, runtimeConfig) => ({
282
+ queryFn: () => getAuthClient(runtimeConfig).getSession(),
283
+ });
284
+
285
+ // Component
286
+ <UserNav runtimeConfig={runtimeConfig} />
287
+ // Inside UserNav: const auth = getAuthClient(runtimeConfig);
288
+ ```
289
+
290
+ Correct:
291
+
292
+ ```typescript
293
+ // auth.ts
294
+ export const sessionQueryOptions = (authClient, initialSession?) => ({
295
+ queryFn: () => authClient.getSession(),
296
+ });
297
+
298
+ // Component
299
+ function UserNav() {
300
+ const auth = useAuthClient();
301
+ }
302
+ ```
303
+
304
+ `runtimeConfig` was threaded through props and query options solely to create auth client instances. With router context, the auth client is a singleton accessed via `useAuthClient()`. No config threading needed.
305
+
306
+ Source: auth.ts:54-67
307
+
308
+ ### HIGH Using near.client.send() without ensureConnected
309
+
310
+ Wrong:
311
+
312
+ ```typescript
313
+ authClient.near.client.transaction(accountId)
314
+ .functionCall(contract, "method", args, opts)
315
+ .send(); // fails if wallet disconnected after sign-in
316
+ ```
317
+
318
+ Correct:
319
+
320
+ ```typescript
321
+ await authClient.near.ensureConnected();
322
+ authClient.near.client.transaction(accountId)
323
+ .functionCall(contract, "method", args, opts)
324
+ .send();
325
+ ```
326
+
327
+ Wallet extensions disconnect between sign-in and subsequent signing. `buildSignedDelegateAction` calls `ensureConnected` automatically, but direct `.send()` does not.
328
+
329
+ Source: src/client.ts:249-253
330
+
331
+ ### MEDIUM Module-level singleton in SSR causes cross-request state leaks
332
+
333
+ Wrong (SSR):
334
+
335
+ ```typescript
336
+ // Module-level singleton — shared across all server requests
337
+ export const authClient = createAuthClient({
338
+ plugins: [siwnClient({ recipient: "myapp.near" })],
339
+ });
340
+ ```
341
+
342
+ Correct (SSR):
343
+
344
+ ```typescript
345
+ // Factory — one instance per router/request
346
+ export function createAuthClient() {
347
+ return createBetterAuthClient({
348
+ plugins: [siwnClient({ recipient: getAccount() })],
349
+ });
350
+ }
351
+ // Created in createRouter() context
352
+ ```
353
+
354
+ On the server, a module-level singleton's `$fetch` and session state would be shared across concurrent requests. Router context isolates one client per request on server, one per app on client.
355
+
356
+ Source: router.server.tsx:60-71