better-near-auth 1.6.3 → 1.6.4

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.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -316,9 +316,12 @@ async function hashNonce(nonce) {
316
316
  const hashBuffer = await crypto.subtle.digest("SHA-256", data);
317
317
  return hex.encode(new Uint8Array(hashBuffer));
318
318
  }
319
- function deriveEmail(accountId) {
320
- if (accountId.endsWith(".near")) return `${accountId.slice(0, -5)}@near.email`;
321
- return null;
319
+ function deriveEmail(accountId, recipient) {
320
+ if (accountId.endsWith(".near")) {
321
+ const localPart = accountId.slice(0, -5);
322
+ if (!localPart.includes(".")) return `${localPart}@near.email`;
323
+ }
324
+ return `temp-${crypto.randomUUID().slice(0, 8)}@${recipient}`;
322
325
  }
323
326
  function nearAccountKey(account) {
324
327
  return `${account.accountId}:${account.network}`;
@@ -1005,7 +1008,7 @@ const siwn = (options) => {
1005
1008
  });
1006
1009
  }
1007
1010
  if (!user) {
1008
- const userEmail = deriveEmail(accountId) ?? "";
1011
+ const userEmail = deriveEmail(accountId, getRecipient(network));
1009
1012
  const profile = await (options.getProfile || ((id) => defaultGetProfile(id, apiKey)))(accountId);
1010
1013
  user = await ctx.context.internalAdapter.createUser({
1011
1014
  name: profile?.name ?? accountId,
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":["z"],"sources":["../src/profile.ts","../src/schema.ts","../src/types.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import type { AccountId, Profile, SocialImage } from \"./types.js\";\n\nconst FALLBACK_URL =\n\t\"https://ipfs.near.social/ipfs/bafkreidn5fb2oygegqaldx7ycdmhu4owcrmoxd7ekbzfmeakkobz2ja7qy\";\n\nfunction getNetworkFromAccountId(accountId: string): \"mainnet\" | \"testnet\" {\n\treturn accountId.endsWith('.testnet') ? 'testnet' : 'mainnet';\n}\n\nfunction getImageUrl(\n\timage: SocialImage | undefined,\n\tfallback?: string,\n): string {\n\tif (image?.url) return image.url;\n\tif (image?.ipfs_cid) return `https://ipfs.near.social/ipfs/${image.ipfs_cid}`;\n\treturn fallback || FALLBACK_URL;\n}\n\ninterface SocialApiResponse {\n\t[accountId: string]: {\n\t\tprofile?: Profile;\n\t};\n}\n\ninterface KvEntry {\n\tvalue: Record<string, unknown> | string;\n\tblock_height?: number;\n\tblock_hash?: string;\n\ttimestamp_nanosec?: string;\n}\n\ninterface KvResponse {\n\tentries: KvEntry[];\n}\n\nasync function defaultGetProfile(accountId: AccountId, apiKey?: string): Promise<Profile | null> {\n\tconst network = getNetworkFromAccountId(accountId);\n\n\ttry {\n\t\tconst kvUrl = network === \"testnet\"\n\t\t\t? \"https://kv.test.fastnear.com\"\n\t\t\t: \"https://kv.main.fastnear.com\";\n\n\t\tconst effectiveApiKey = apiKey || process.env.FASTNEAR_API_KEY;\n\t\tconst headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n\t\tif (effectiveApiKey) {\n\t\t\theaders[\"Authorization\"] = `Bearer ${effectiveApiKey}`;\n\t\t}\n\n\t\tconst response = await fetch(\n\t\t\t`${kvUrl}/v0/latest/social.near/${accountId}/profile/**`,\n\t\t\t{ headers },\n\t\t);\n\n\t\tif (response.ok) {\n\t\t\tconst data = await response.json() as KvResponse;\n\t\t\tconst entry = data?.entries?.[0];\n\t\t\tif (entry?.value) {\n\t\t\t\ttry {\n\t\t\t\t\tconst profile = typeof entry.value === \"string\"\n\t\t\t\t\t\t? JSON.parse(entry.value)\n\t\t\t\t\t\t: entry.value;\n\t\t\t\t\tif (profile?.name || profile?.description || profile?.image) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: profile.name,\n\t\t\t\t\t\t\tdescription: profile.description,\n\t\t\t\t\t\t\timage: profile.image,\n\t\t\t\t\t\t\tbackgroundImage: profile.backgroundImage,\n\t\t\t\t\t\t\tlinktree: profile.linktree,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t}\n\n\t\tconst apiBase = {\n\t\t\tmainnet: \"https://api.near.social\",\n\t\t\ttestnet: \"https://test.api.near.social\",\n\t\t}[network];\n\n\t\tconst keys = [`${accountId}/profile/**`];\n\n\t\tconst fallbackResponse = await fetch(`${apiBase}/get`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ keys })\n\t\t});\n\n\t\tif (!fallbackResponse.ok) {\n\t\t\tthrow new Error(`HTTP error! status: ${fallbackResponse.status}`);\n\t\t}\n\n\t\tconst fallbackData = await fallbackResponse.json() as SocialApiResponse;\n\t\tconst profile: Profile | undefined = fallbackData?.[accountId]?.profile;\n\n\t\tif (profile) {\n\t\t\treturn {\n\t\t\t\tname: profile.name,\n\t\t\t\tdescription: profile.description,\n\t\t\t\timage: profile.image,\n\t\t\t\tbackgroundImage: profile.backgroundImage,\n\t\t\t\tlinktree: profile.linktree\n\t\t\t};\n\t\t}\n\t\treturn null;\n\t} catch (error) {\n\t\treturn null;\n\t}\n}\n\nexport { defaultGetProfile, getImageUrl, getNetworkFromAccountId };\n","import type { BetterAuthPluginDBSchema } from \"better-auth/db\";\n\nexport const schema = {\n\tnearAccount: {\n\t\tfields: {\n\t\t\tuserId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\treferences: {\n\t\t\t\t\tmodel: \"user\",\n\t\t\t\t\tfield: \"id\",\n\t\t\t\t},\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\taccountId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tnetwork: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tpublicKey: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tisPrimary: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefaultValue: false,\n\t\t\t},\n\t\t\tcreatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t},\n\t},\n\trelayedTransaction: {\n\t\tfields: {\n\t\t\tuserId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\treferences: {\n\t\t\t\t\tmodel: \"user\",\n\t\t\t\t\tfield: \"id\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttxHash: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tsenderId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\treceiverId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tnetwork: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tstatus: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tgasUsed: {\n\t\t\t\ttype: \"string\",\n\t\t\t},\n\t\t\tcreatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tupdatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t},\n\t\t},\n\t},\n\trelayerKey: {\n\t\tfields: {\n\t\t\taccountId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tencryptedPrivateKey: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tiv: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tpublicKey: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tnetwork: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tcreatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tlastUsedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t},\n\t\t},\n\t},\n} satisfies BetterAuthPluginDBSchema;\n","import { z } from \"zod\";\nimport { AccountIdSchema, type AccountId } from \"near-kit/schemas\";\nimport type { AccountState } from \"near-kit\";\n\nexport type { AccountId };\n\nexport interface NearAccount {\n\tid: string;\n\tuserId: string;\n\taccountId: string;\n\tnetwork: \"mainnet\" | \"testnet\";\n\tpublicKey: string;\n\tisPrimary: boolean;\n\tcreatedAt: Date;\n}\n\nexport interface ListedNearAccount extends NearAccount {\n\tproviderId: \"siwn\";\n\tisActive: boolean;\n\tisAvailable: boolean;\n}\n\nexport interface ListAccountsResponseT {\n\taccounts: ListedNearAccount[];\n\tactiveAccount: ListedNearAccount | null;\n\tavailableAccounts: ListedNearAccount[];\n}\n\nexport interface SetPrimaryAccountResponseT extends ListAccountsResponseT {\n\tsuccess: boolean;\n\taccountId: string;\n\tnetwork: \"mainnet\" | \"testnet\";\n\tmessage: string;\n}\n\nexport const socialImageSchema = z.object({\n\turl: z.string().optional(),\n\tipfs_cid: z.string().optional(),\n});\n\nexport const profileSchema = z.object({\n\tname: z.string().optional(),\n\tdescription: z.string().optional(),\n\timage: socialImageSchema.optional(),\n\tbackgroundImage: socialImageSchema.optional(),\n\tlinktree: z.record(z.string(), z.string()).optional(),\n});\n\nexport type SocialImage = z.infer<typeof socialImageSchema>;\nexport type Profile = z.infer<typeof profileSchema>;\n\nconst signedMessageSchema = z.object({\n\taccountId: z.string(),\n\tpublicKey: z.string(),\n\tsignature: z.string(),\n\tstate: z.string().optional(),\n});\n\nexport const LinkAccountRequest = z.object({\n\tsignedMessage: signedMessageSchema,\n\tmessage: z.string(),\n\trecipient: z.string(),\n\tnonce: z.string(),\n\taccountId: AccountIdSchema,\n});\n\nexport const SetPrimaryAccountRequest = z.object({\n\taccountId: AccountIdSchema,\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n});\n\nexport const NonceRequest = z.object({\n\taccountId: AccountIdSchema,\n\tnetworkId: z.union([z.literal(\"mainnet\"), z.literal(\"testnet\")])\n});\n\nexport const VerifyRequest = z.object({\n\tsignedMessage: signedMessageSchema,\n\tmessage: z.string(),\n\trecipient: z.string(),\n\tnonce: z.string(),\n\taccountId: AccountIdSchema,\n});\n\nexport const RelayRequest = z.object({\n\tpayload: z.string(),\n});\nexport type RelayRequestT = z.infer<typeof RelayRequest>;\n\nexport const RelayResponse = z.object({\n\ttxHash: z.string(),\n\tstatus: z.enum([\"pending\", \"completed\", \"failed\"]),\n});\nexport type RelayResponseT = z.infer<typeof RelayResponse>;\n\nexport const RelayStatusResponse = z.object({\n\tstatus: z.enum([\"pending\", \"completed\", \"failed\"]),\n\tgasUsed: z.string().optional(),\n\toutcome: z.unknown().optional(),\n});\nexport type RelayStatusResponseT = z.infer<typeof RelayStatusResponse>;\n\nexport const ViewContractRequest = z.object({\n\tcontractId: z.string(),\n\tmethodName: z.string(),\n\targs: z.record(z.string(), z.any()).optional(),\n});\nexport type ViewContractRequestT = z.infer<typeof ViewContractRequest>;\n\nexport const NonceResponse = z.object({ nonce: z.string() });\nexport const VerifyResponse = z.object({\n\ttoken: z.string(),\n\tsuccess: z.literal(true),\n\tuser: z.object({\n\t\tid: z.string(),\n\t\taccountId: AccountIdSchema,\n\t\tnetwork: z.union([z.literal(\"mainnet\"), z.literal(\"testnet\")]),\n\t}),\n});\nexport const ProfileResponse = profileSchema.nullable();\nexport const ViewContractResponse = z.object({ result: z.unknown() });\n\nexport const ProfileRequest = z.object({\n\taccountId: AccountIdSchema.optional(),\n});\nexport type ProfileRequestT = z.infer<typeof ProfileRequest>;\n\nexport type NonceRequestT = z.infer<typeof NonceRequest>;\nexport type NonceResponseT = z.infer<typeof NonceResponse>;\nexport type SetPrimaryAccountRequestT = z.infer<typeof SetPrimaryAccountRequest>;\nexport type VerifyRequestT = z.infer<typeof VerifyRequest>;\nexport type VerifyResponseT = z.infer<typeof VerifyResponse>;\nexport type ProfileResponseT = z.infer<typeof ProfileResponse>;\nexport type ViewContractResponseT = z.infer<typeof ViewContractResponse>;\n\nexport const RelayedTransactionSchema = z.object({\n\tid: z.string(),\n\tuserId: z.string(),\n\ttxHash: z.string(),\n\tsenderId: z.string(),\n\treceiverId: z.string(),\n\tnetwork: z.string(),\n\tstatus: z.string(),\n\tgasUsed: z.string().optional(),\n\tcreatedAt: z.string(),\n\tupdatedAt: z.string().optional(),\n});\nexport type RelayedTransactionT = z.infer<typeof RelayedTransactionSchema>;\n\nexport const RelayHistoryResponse = z.object({\n\ttransactions: z.array(RelayedTransactionSchema),\n});\nexport type RelayHistoryResponseT = z.infer<typeof RelayHistoryResponse>;\n\nexport interface RelayedTransactionRecord {\n\tid: string;\n\tuserId: string;\n\ttxHash: string;\n\tsenderId: string;\n\treceiverId: string;\n\tnetwork: \"mainnet\" | \"testnet\";\n\tstatus: string;\n\tgasUsed?: string;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n}\n\nexport interface RelayerInfo extends AccountState {\n\taccountId: string;\n\tmode: \"ephemeral\" | \"explicit\";\n\tnetwork: \"mainnet\" | \"testnet\";\n\tpublicKey: string;\n\thasKey: boolean;\n\tcreatedAt?: Date;\n\tlastUsedAt?: Date;\n\tparentAccount?: string;\n\tsubAccountAvailable?: boolean;\n}\n\nexport interface DualNetworkConfig<T> {\n\tmainnet: T;\n\ttestnet: T;\n}\n\nexport const GetRelayerInfoRequest = z.object({\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n});\nexport type GetRelayerInfoRequestT = z.infer<typeof GetRelayerInfoRequest>;\n\nexport interface SubAccountRelayerFCAKConfig {\n\treceiverId: string;\n\tmethodNames?: string[];\n\tallowance?: string;\n}\n\nexport interface SubAccountConfig {\n\tparentAccount?: string;\n\tparentKey?: string;\n\tminDeposit?: string;\n\taddRelayerFCAK?: boolean;\n\trelayerFCAK?: SubAccountRelayerFCAKConfig;\n}\n\nexport const CreateSubAccountRequest = z.object({\n\tsubAccountName: z.string().regex(/^[a-z0-9]+$/, \"Must be lowercase alphanumeric characters only\"),\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n\tpublicKey: z.string(),\n});\nexport type CreateSubAccountRequestT = z.infer<typeof CreateSubAccountRequest>;\n\nexport const CreateSubAccountResponse = z.object({\n\tsuccess: z.literal(true),\n\taccountId: z.string(),\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]),\n\tpublicKey: z.string(),\n\tmessage: z.string(),\n});\nexport type CreateSubAccountResponseT = z.infer<typeof CreateSubAccountResponse>;\n\nexport const CheckSubAccountAvailabilityRequest = z.object({\n\tsubAccountName: z.string().regex(/^[a-z0-9]+$/),\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n});\nexport type CheckSubAccountAvailabilityRequestT = z.infer<typeof CheckSubAccountAvailabilityRequest>;\n\nexport const CheckSubAccountAvailabilityResponse = z.object({\n\tavailable: z.boolean(),\n\taccountId: z.string(),\n});\nexport type CheckSubAccountAvailabilityResponseT = z.infer<typeof CheckSubAccountAvailabilityResponse>;\n","export function bytesToBase64(bytes: Uint8Array): string {\n\treturn btoa(String.fromCharCode(...bytes));\n}\n\nfunction base64ToBytes(base64: string): Uint8Array {\n\treturn Uint8Array.from(atob(base64), c => c.charCodeAt(0));\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n\treturn Array.from(bytes).map(b => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n\tconst bytes = new Uint8Array(hex.length / 2);\n\tfor (let i = 0; i < hex.length; i += 2) {\n\t\tbytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n\t}\n\treturn bytes;\n}\n\nasync function deriveAesKey(secret: string): Promise<CryptoKey> {\n\tconst keyMaterial = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tnew TextEncoder().encode(secret),\n\t\t{ name: \"HKDF\" },\n\t\tfalse,\n\t\t[\"deriveKey\"],\n\t);\n\treturn crypto.subtle.deriveKey(\n\t\t{\n\t\t\tname: \"HKDF\",\n\t\t\thash: \"SHA-256\",\n\t\t\tsalt: new TextEncoder().encode(\"better-near-auth-relayer\"),\n\t\t\tinfo: new Uint8Array(0),\n\t\t},\n\t\tkeyMaterial,\n\t\t{ name: \"AES-GCM\", length: 256 },\n\t\tfalse,\n\t\t[\"encrypt\", \"decrypt\"],\n\t);\n}\n\nexport async function encryptPrivateKey(\n\tprivateKey: Uint8Array,\n\tsecret: string,\n): Promise<{ encrypted: string; iv: string }> {\n\tconst aesKey = await deriveAesKey(secret);\n\tconst iv = crypto.getRandomValues(new Uint8Array(12));\n\tconst encrypted = await crypto.subtle.encrypt(\n\t\t{ name: \"AES-GCM\", iv },\n\t\taesKey,\n\t\tprivateKey as Uint8Array<ArrayBuffer>,\n\t);\n\treturn {\n\t\tencrypted: bytesToBase64(new Uint8Array(encrypted)),\n\t\tiv: bytesToBase64(iv),\n\t};\n}\n\nexport async function decryptPrivateKey(\n\tencrypted: string,\n\tiv: string,\n\tsecret: string,\n): Promise<Uint8Array> {\n\tconst aesKey = await deriveAesKey(secret);\n\tconst decrypted = await crypto.subtle.decrypt(\n\t\t{ name: \"AES-GCM\", iv: base64ToBytes(iv) as Uint8Array<ArrayBuffer> },\n\t\taesKey,\n\t\tbase64ToBytes(encrypted) as Uint8Array<ArrayBuffer>,\n\t);\n\treturn new Uint8Array(decrypted);\n}\n","import { APIError, createAuthEndpoint, createAuthMiddleware, sessionMiddleware } from \"better-auth/api\";\nimport { setSessionCookie } from \"better-auth/cookies\";\nimport type { Account, User, DBAdapter } from \"better-auth/types\";\n// Explicit type imports for declaration emit\nimport type {} from \"@better-auth/core/env\";\nimport type {} from \"@better-auth/core/oauth2\";\nimport type {} from \"better-call\";\n\nimport { Near, generateNonce, generateKey, parseKey, verifyNep413Signature, decodeSignedDelegateAction, InMemoryKeyStore, RotatingKeyStore } from \"near-kit\";\nimport type { SignedDelegateAction, PrivateKey } from \"near-kit\";\nimport { hex, base58 } from \"@scure/base\";\nimport z from \"zod\";\nimport { defaultGetProfile, getImageUrl, getNetworkFromAccountId } from \"./profile.js\";\nimport { schema } from \"./schema.js\";\nimport {\n\ttype AccountId,\n\ttype DualNetworkConfig,\n\ttype ListAccountsResponseT,\n\ttype ListedNearAccount,\n\ttype NearAccount,\n\ttype Profile,\n\ttype RelayerInfo,\n\ttype RelayedTransactionRecord,\n\ttype SubAccountConfig,\n\tLinkAccountRequest,\n\tNonceRequest,\n\tNonceResponse,\n\tProfileRequest,\n\tProfileResponse,\n\tVerifyRequest,\n\tVerifyResponse,\n\tRelayRequest,\n\tRelayResponse,\n\tRelayStatusResponse,\n\tSetPrimaryAccountRequest,\n\tViewContractRequest,\n\tViewContractResponse,\n\tGetRelayerInfoRequest,\n\tCreateSubAccountRequest,\n\tCreateSubAccountResponse,\n\tCheckSubAccountAvailabilityRequest,\n\tCheckSubAccountAvailabilityResponse,\n} from \"./types.js\";\nexport * from \"./types.js\";\nimport {\n\tbytesToHex,\n\tencryptPrivateKey,\n\tdecryptPrivateKey,\n} from \"./utils.js\";\n\nasync function hashNonce(nonce: Uint8Array): Promise<string> {\n\tconst data = new TextEncoder().encode(hex.encode(nonce));\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', data);\n\treturn hex.encode(new Uint8Array(hashBuffer));\n}\n\nfunction deriveEmail(accountId: string): string | null {\n\tif (accountId.endsWith(\".near\")) {\n\t\tconst localPart = accountId.slice(0, -5);\n\t\treturn `${localPart}@near.email`;\n\t}\n\treturn null;\n}\n\nfunction nearAccountKey(account: Pick<NearAccount, \"accountId\" | \"network\">): string {\n\treturn `${account.accountId}:${account.network}`;\n}\n\nfunction getCreatedAtTime(account: NearAccount): number {\n\treturn account.createdAt instanceof Date\n\t\t? account.createdAt.getTime()\n\t\t: new Date(account.createdAt).getTime();\n}\n\nfunction buildListAccountsResponse(nearAccounts: NearAccount[]): ListAccountsResponseT {\n\tconst activeAccount = nearAccounts.find((account) => account.isPrimary) ?? nearAccounts[0] ?? null;\n\tconst activeKey = activeAccount ? nearAccountKey(activeAccount) : null;\n\tconst accounts: ListedNearAccount[] = nearAccounts\n\t\t.map((account) => {\n\t\t\tconst isActive = activeKey === nearAccountKey(account);\n\t\t\treturn {\n\t\t\t\t...account,\n\t\t\t\tproviderId: \"siwn\" as const,\n\t\t\t\tisActive,\n\t\t\t\tisAvailable: !isActive,\n\t\t\t};\n\t\t})\n\t\t.sort((a, b) => {\n\t\t\tif (a.isActive !== b.isActive) return a.isActive ? -1 : 1;\n\t\t\treturn getCreatedAtTime(a) - getCreatedAtTime(b);\n\t\t});\n\tconst listedActiveAccount = accounts.find((account) => account.isActive) ?? null;\n\n\treturn {\n\t\taccounts,\n\t\tactiveAccount: listedActiveAccount ? { ...listedActiveAccount } : null,\n\t\tavailableAccounts: accounts\n\t\t\t.filter((account) => account.isAvailable)\n\t\t\t.map((account) => ({ ...account })),\n\t};\n}\n\nexport interface RelayerConfig {\n\taccountId?: string;\n\tprivateKey?: string;\n\tprivateKeys?: string[];\n\twhitelistedContracts?: string[];\n\tmaxGasPerTransaction?: string;\n\tmaxDepositPerTransaction?: string;\n}\n\ninterface RelayerState {\n\tnear: Near;\n\taccountId: string;\n\tnetwork: \"mainnet\" | \"testnet\";\n\tmode: \"ephemeral\" | \"explicit\";\n\tpublicKey: string;\n\tcreatedAt?: Date;\n\tlastUsedAt?: Date;\n}\n\nfunction createNear(\n\tnetwork: \"mainnet\" | \"testnet\",\n\theaders: Record<string, string>,\n\trpcUrl?: string,\n\tkeyStore?: InMemoryKeyStore | RotatingKeyStore,\n): Near {\n\tconst config: ConstructorParameters<typeof Near>[0] = { headers };\n\tif (rpcUrl) {\n\t\tconfig.network = { rpcUrl, networkId: network };\n\t} else {\n\t\tconfig.network = network;\n\t}\n\tif (keyStore) {\n\t\tconfig.keyStore = keyStore;\n\t}\n\treturn new Near(config);\n}\n\nasync function initRelayer(\n\trelayerConfig: RelayerConfig | undefined,\n\tnetwork: \"mainnet\" | \"testnet\",\n\tadapter: DBAdapter,\n\tsecret: string | undefined,\n\tapiKey?: string,\n\trpcUrl?: string,\n): Promise<RelayerState | null> {\n\tif (!relayerConfig) return null;\n\n\tconst headers: Record<string, string> = {};\n\tif (apiKey) {\n\t\theaders[\"Authorization\"] = `Bearer ${apiKey}`;\n\t}\n\n\tif (relayerConfig.accountId && (relayerConfig.privateKey || relayerConfig.privateKeys)) {\n\t\tconst keys = relayerConfig.privateKeys ?? (relayerConfig.privateKey ? [relayerConfig.privateKey] : []);\n\t\tlet keyStore: InMemoryKeyStore | RotatingKeyStore;\n\n\t\tif (keys.length === 1) {\n\t\t\tkeyStore = new InMemoryKeyStore({\n\t\t\t\t[relayerConfig.accountId]: keys[0]!,\n\t\t\t});\n\t\t} else {\n\t\t\tkeyStore = new RotatingKeyStore({\n\t\t\t\t[relayerConfig.accountId]: keys as string[],\n\t\t\t});\n\t\t}\n\n\t\tconst near = createNear(network, headers, rpcUrl, keyStore);\n\t\tconst explicitPublicKey = parseKey(keys[0]!);\n\t\treturn {\n\t\t\tnear,\n\t\t\taccountId: relayerConfig.accountId,\n\t\t\tnetwork,\n\t\t\tmode: \"explicit\",\n\t\t\tpublicKey: explicitPublicKey.publicKey.toString(),\n\t\t};\n\t}\n\n\tconst existing = await adapter.findOne<{ encryptedPrivateKey: string; iv: string; createdAt: Date; lastUsedAt: Date }>({\n\t\tmodel: \"relayerKey\",\n\t\twhere: [{ field: \"network\", operator: \"eq\", value: network }],\n\t});\n\n\tif (existing) {\n\t\tif (!secret) throw new Error(\"BETTER_AUTH_SECRET required for relayer key decryption\");\n\t\tconst privateKeyBytes = await decryptPrivateKey(existing.encryptedPrivateKey, existing.iv, secret);\n\t\tconst keyPair = parseKey(`ed25519:${base58.encode(privateKeyBytes)}`);\n\t\tconst accountId = bytesToHex(keyPair.publicKey.data);\n\n\t\tconsole.log(`[siwn] Relayer recovered: ${accountId} (${network})`);\n\n\t\tconst keyStore = new InMemoryKeyStore();\n\t\tawait keyStore.add(accountId, keyPair);\n\n\t\tconst near = createNear(network, headers, rpcUrl, keyStore);\n\t\treturn {\n\t\t\tnear,\n\t\t\taccountId,\n\t\t\tnetwork,\n\t\t\tmode: \"ephemeral\",\n\t\t\tpublicKey: keyPair.publicKey.toString(),\n\t\t\tcreatedAt: existing.createdAt,\n\t\t\tlastUsedAt: existing.lastUsedAt,\n\t\t};\n\t}\n\n\tconst keyPair = generateKey();\n\tif (!secret) throw new Error(\"BETTER_AUTH_SECRET required for relayer key encryption\");\n\tconst privateKeyBytes = keyPair.secretKey.startsWith(\"ed25519:\")\n\t\t? base58.decode(keyPair.secretKey.slice(8))\n\t\t: new Uint8Array(0);\n\n\tconst publicKeyBase58 = keyPair.publicKey.toString().replace(\"ed25519:\", \"\");\n\tconst accountId = bytesToHex(keyPair.publicKey.data);\n\tconst createdAt = new Date();\n\n\tconst { encrypted, iv } = await encryptPrivateKey(privateKeyBytes, secret);\n\n\tawait adapter.create({\n\t\t\tmodel: \"relayerKey\",\n\t\t\tdata: {\n\t\t\t\taccountId,\n\t\t\t\tencryptedPrivateKey: encrypted,\n\t\t\t\tiv,\n\t\t\t\tpublicKey: `ed25519:${publicKeyBase58}`,\n\t\t\t\tnetwork,\n\t\t\t\tcreatedAt,\n\t\t\t\tlastUsedAt: createdAt,\n\t\t\t},\n\t\t});\n\n\tconsole.log(`[siwn] Relayer created in EPHEMERAL mode: ${accountId} (${network})`);\n\tconsole.log(`[siwn] Fund this account with NEAR to enable gasless relay`);\n\tconsole.log(`[siwn] Private key is encrypted in DB — persists across restarts`);\n\n\tconst keyStore = new InMemoryKeyStore();\n\tawait keyStore.add(accountId, keyPair);\n\n\tconst near = createNear(network, headers, rpcUrl, keyStore);\n\treturn {\n\t\tnear,\n\t\taccountId,\n\t\tnetwork,\n\t\tmode: \"ephemeral\",\n\t\tpublicKey: keyPair.publicKey.toString(),\n\t\tcreatedAt,\n\t\tlastUsedAt: createdAt,\n\t};\n}\n\nasync function relayOnChain(\n\tpayload: string,\n\trelayerState: RelayerState,\n): Promise<{ txHash: string }> {\n\tconst userAction = decodeSignedDelegateAction(payload);\n\n\tconst result = await relayerState.near\n\t\t.transaction(relayerState.accountId)\n\t\t.signedDelegateAction(userAction)\n\t\t.send({ waitUntil: \"EXECUTED\" });\n\n\treturn { txHash: result.transaction.hash };\n}\n\nasync function defaultValidateLimitedAccessKey(\n\taccountId: string,\n\tpublicKey: string,\n\trecipient: string,\n\tnear: Near,\n): Promise<boolean> {\n\tconst key = await near.getAccessKey(accountId, publicKey);\n\tif (!key) return false;\n\tif (key.permission === \"FullAccess\") return true;\n\tif (\"FunctionCall\" in key.permission) {\n\t\treturn key.permission.FunctionCall.receiver_id === recipient;\n\t}\n\treturn false;\n}\n\nfunction isImplicitAccount(accountId: string): boolean {\n\treturn /^[0-9a-f]{64}$/.test(accountId);\n}\n\nfunction resolveParentAccount(\n\tsubAccountCfg: SubAccountConfig | undefined,\n\trState: RelayerState | null,\n): { parentAccount: string | null; subAccountAvailable: boolean } {\n\tif (!rState) return { parentAccount: null, subAccountAvailable: false };\n\tconst parent = subAccountCfg?.parentAccount ?? rState.accountId;\n\tif (!parent || isImplicitAccount(parent)) {\n\t\treturn { parentAccount: null, subAccountAvailable: false };\n\t}\n\treturn { parentAccount: parent, subAccountAvailable: true };\n}\n\nexport interface SIWNPluginOptions {\n\trecipient?: string;\n\trecipients?: DualNetworkConfig<string>;\n\trequireFullAccessKey?: boolean;\n\tgetNonce?: () => Promise<Uint8Array>;\n\tgetProfile?: (accountId: AccountId) => Promise<Profile | null>;\n\tvalidateLimitedAccessKey?: (args: {\n\t\taccountId: AccountId;\n\t\tpublicKey: string;\n\t\trecipient?: string;\n\t}) => Promise<boolean>;\n\tapiKey?: string;\n\trpcUrl?: string | DualNetworkConfig<string>;\n\trelayer?: RelayerConfig | DualNetworkConfig<RelayerConfig>;\n\tsubAccount?: SubAccountConfig | DualNetworkConfig<SubAccountConfig>;\n}\n\nexport const siwn = (options: SIWNPluginOptions) => {\n\tif (!options.recipient && !options.recipients) {\n\t\tthrow new Error(\"Either 'recipient' or 'recipients' must be provided to siwn plugin\");\n\t}\n\n\tconst apiKey = options.apiKey;\n\n\tconst getRecipient = (network: \"mainnet\" | \"testnet\"): string => {\n\t\tif (options.recipients) return options.recipients[network];\n\t\treturn options.recipient!;\n\t};\n\n\tconst getSupportedNetworks = (): (\"mainnet\" | \"testnet\")[] => {\n\t\tif (options.recipients) return [\"mainnet\", \"testnet\"];\n\t\tif (options.recipient) return [getNetworkFromAccountId(options.recipient)];\n\t\treturn [\"mainnet\"];\n\t};\n\n\tconst getRelayerConfig = (network: \"mainnet\" | \"testnet\"): RelayerConfig | undefined => {\n\t\tif (!options.relayer) return undefined;\n\t\tif (\"mainnet\" in options.relayer && typeof options.relayer.mainnet === \"object\") {\n\t\t\treturn (options.relayer as DualNetworkConfig<RelayerConfig>)[network];\n\t\t}\n\t\treturn options.relayer as RelayerConfig;\n\t};\n\n\tconst getRpcUrl = (network: \"mainnet\" | \"testnet\"): string | undefined => {\n\t\tif (!options.rpcUrl) return undefined;\n\t\tif (typeof options.rpcUrl === \"object\") return (options.rpcUrl as DualNetworkConfig<string>)[network];\n\t\treturn options.rpcUrl as string;\n\t};\n\n\tconst getSubAccountConfig = (network: \"mainnet\" | \"testnet\"): SubAccountConfig | undefined => {\n\t\tif (!options.subAccount) return undefined;\n\t\tif (\"mainnet\" in options.subAccount && typeof options.subAccount.mainnet === \"object\") {\n\t\t\treturn (options.subAccount as DualNetworkConfig<SubAccountConfig>)[network];\n\t\t}\n\t\treturn options.subAccount as SubAccountConfig;\n\t};\n\n\tconst primaryNetwork = getSupportedNetworks()[0];\n\tconst relayerStates = new Map<\"mainnet\" | \"testnet\", RelayerState | null>();\n\tconst relayerInitPromises = new Map<\"mainnet\" | \"testnet\", Promise<RelayerState | null>>();\n\n\tconst headers: Record<string, string> = {};\n\tif (apiKey) {\n\t\theaders[\"Authorization\"] = `Bearer ${apiKey}`;\n\t}\n\n\tconst ensureRelayer = async (adapter: DBAdapter, secret: string | undefined, network: \"mainnet\" | \"testnet\") => {\n\t\tif (relayerStates.has(network)) return relayerStates.get(network) ?? null;\n\n\t\tconst existingInit = relayerInitPromises.get(network);\n\t\tif (existingInit) return existingInit;\n\n\t\tconst relayerCfg = getRelayerConfig(network);\n\t\tconst networkRpcUrl = getRpcUrl(network);\n\n\t\tconst initPromise = initRelayer(relayerCfg, network, adapter, secret, apiKey, networkRpcUrl)\n\t\t\t.then((state) => {\n\t\t\t\trelayerStates.set(network, state);\n\t\t\t\trelayerInitPromises.delete(network);\n\t\t\t\treturn state;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\trelayerInitPromises.delete(network);\n\t\t\t\tthrow error;\n\t\t\t});\n\n\t\trelayerInitPromises.set(network, initPromise);\n\t\treturn initPromise;\n\t};\n\n\tconst getNear = (network: \"mainnet\" | \"testnet\") => {\n\t\tconst networkRpcUrl = getRpcUrl(network);\n\t\tif (networkRpcUrl) {\n\t\t\treturn new Near({ network: { rpcUrl: networkRpcUrl, networkId: network }, headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined });\n\t\t}\n\t\treturn new Near({ network, headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined });\n\t};\n\n\treturn ({\n\t\tid: \"siwn\",\n\t\tschema,\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher: (context: { path?: string; method?: string }) => context.path === \"/auth/session\" && context.method === \"GET\",\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\t\tif (session) {\n\t\t\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (nearAccount) {\n\t\t\t\t\t\t\t\tctx.context.session = {\n\t\t\t\t\t\t\t\t\t...session,\n\t\t\t\t\t\t\t\t\tuser: {\n\t\t\t\t\t\t\t\t\t\t...session.user,\n\t\t\t\t\t\t\t\t\t\tnearAccount: nearAccount\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn { context: ctx };\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tendpoints: {\n\t\t\tlinkNearAccount: createAuthEndpoint(\n\t\t\t\t\"/near/link-account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: LinkAccountRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t\trequireRequest: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { signedMessage, message, recipient, nonce, accountId } = ctx.body;\n\t\t\t\t\tconst network = getNetworkFromAccountId(accountId);\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Must be logged in to link NEAR account\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\t\tconst nonceBytes = hex.decode(nonce);\n\n\t\t\t\t\t\tconst isValid = await verifyNep413Signature(\n\t\t\t\t\t\tsignedMessage,\n\t\t\t\t\t\t{ message, recipient, nonce: nonceBytes },\n\t\t\t\t\t\t\t{ near, maxAge: 15 * 60 * 1000 },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Invalid signature\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (signedMessage.accountId !== accountId) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Account ID mismatch\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst publicKey = signedMessage.publicKey;\n\n\t\t\t\t\t\tif (!options.requireFullAccessKey && options.validateLimitedAccessKey) {\n\t\t\t\t\t\t\tconst isValidKey = await options.validateLimitedAccessKey({\n\t\t\t\t\t\t\t\taccountId: accountId,\n\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\trecipient: options.recipient\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (!isValidKey) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Invalid function call access key\",\n\t\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst existingNearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (existingNearAccount) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage: \"This NEAR account is already linked to another user\",\n\t\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst existingPrimaryAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\tisPrimary: !existingPrimaryAccount,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tproviderId: \"siwn\",\n\t\t\t\t\t\t\taccountId: `${accountId}:${network}`,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\tmessage: \"NEAR account successfully linked\"\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (error instanceof APIError) throw error;\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Something went wrong. Please try again later.\",\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : \"Unknown error\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tunlinkNearAccount: createAuthEndpoint(\n\t\t\t\t\"/near/unlink-account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\taccountId: z.string(),\n\t\t\t\t\t\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n\t\t\t\t\t}),\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { accountId, network: providedNetwork } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Must be logged in to unlink NEAR account\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst network = providedNetwork || getNetworkFromAccountId(accountId);\n\n\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!nearAccount) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"NEAR account not found or not linked to your user\",\n\t\t\t\t\t\t\tstatus: 404,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst accounts = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"account\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", operator: \"eq\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (accounts.length <= 1) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Cannot unlink last authentication method. Link another account first.\",\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (nearAccount.isPrimary) {\n\t\t\t\t\t\tconst otherNearAccounts: NearAccount[] = await ctx.context.adapter.findMany({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"ne\", value: accountId },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (otherNearAccounts.length > 0) {\n\t\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t{ field: \"id\", operator: \"eq\", value: otherNearAccounts[0]!.id },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tupdate: { isPrimary: true },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tawait ctx.context.adapter.delete({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tconst accountToDelete: Account | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"account\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"providerId\", operator: \"eq\", value: \"siwn\" },\n\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: `${accountId}:${network}` },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (accountToDelete) {\n\t\t\t\t\t\tawait ctx.context.internalAdapter.deleteAccount(accountToDelete.id);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\taccountId,\n\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\tmessage: \"NEAR account successfully unlinked\"\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tlistNearAccounts: createAuthEndpoint(\n\t\t\t\t\"/near/list-accounts\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tconst nearAccounts: NearAccount[] = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", operator: \"eq\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json(buildListAccountsResponse(nearAccounts));\n\t\t\t\t},\n\t\t\t),\n\t\t\tsetPrimaryNearAccount: createAuthEndpoint(\n\t\t\t\t\"/near/set-primary-account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: SetPrimaryAccountRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { accountId, network: providedNetwork } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tconst network = providedNetwork || getNetworkFromAccountId(accountId);\n\n\t\t\t\t\tconst targetAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!targetAccount) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"NEAR account not found or not linked to your user\",\n\t\t\t\t\t\t\tstatus: 404,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nearAccounts: NearAccount[] = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", operator: \"eq\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\tawait Promise.all(nearAccounts.map((account) => ctx.context.adapter.update({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [{ field: \"id\", operator: \"eq\", value: account.id }],\n\t\t\t\t\t\tupdate: { isPrimary: nearAccountKey(account) === nearAccountKey(targetAccount) },\n\t\t\t\t\t})));\n\n\t\t\t\t\tconst updatedNearAccounts: NearAccount[] = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", operator: \"eq\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\taccountId,\n\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\tmessage: \"Primary NEAR account updated\",\n\t\t\t\t\t\t...buildListAccountsResponse(updatedNearAccounts),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetSiwnNonce: createAuthEndpoint(\n\t\t\t\t\"/near/nonce\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: NonceRequest,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { accountId, networkId } = ctx.body;\n\t\t\t\t\tconst network = getNetworkFromAccountId(accountId);\n\n\t\t\t\t\tif (networkId !== network) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Network ID mismatch with account ID\",\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\tconst exists = await near.accountExists(accountId);\n\t\t\t\t\tif (!exists) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Account does not exist on-chain\",\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nonce = options.getNonce ? await options.getNonce() : generateNonce();\n\n\t\t\t\t\tconst nonceString = hex.encode(nonce);\n\n\t\t\t\t\tawait ctx.context.internalAdapter.createVerificationValue({\n\t\t\t\t\t\tidentifier: `siwn:${accountId}:${network}`,\n\t\t\t\t\t\tvalue: nonceString,\n\t\t\t\t\t\texpiresAt: new Date(Date.now() + 15 * 60 * 1000),\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json(NonceResponse.parse({ nonce: nonceString }));\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetSiwnProfile: createAuthEndpoint(\n\t\t\t\t\"/near/profile\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: ProfileRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { accountId } = ctx.body;\n\t\t\t\t\tlet targetAccountId = accountId;\n\n\t\t\t\t\tif (!targetAccountId) {\n\t\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\t\tif (!session) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Session required when no accountId provided\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!nearAccount) {\n\t\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\t\tmessage: \"No NEAR account found for user\",\n\t\t\t\t\t\t\t\tstatus: 404,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetAccountId = nearAccount.accountId;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst profile = await (options.getProfile || ((id: AccountId) => defaultGetProfile(id, apiKey)))(targetAccountId);\n\t\t\t\t\treturn ctx.json(ProfileResponse.parse(profile));\n\t\t\t\t},\n\t\t\t),\n\t\t\tverifySiwnMessage: createAuthEndpoint(\n\t\t\t\t\"/near/verify\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: VerifyRequest,\n\t\t\t\t\trequireRequest: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst {\n\t\t\t\t\t\tsignedMessage,\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t\trecipient,\n\t\t\t\t\t\tnonce,\n\t\t\t\t\t\taccountId,\n\t\t\t\t\t} = ctx.body;\n\t\t\t\t\tconst network = getNetworkFromAccountId(accountId);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\t\tconst nonceBytes = hex.decode(nonce);\n\n\t\t\t\t\t\tconst isValid = await verifyNep413Signature(\n\t\t\t\t\t\tsignedMessage,\n\t\t\t\t\t\t{ message, recipient, nonce: nonceBytes },\n\t\t\t\t\t\t\t{ near, maxAge: 15 * 60 * 1000 },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Invalid signature\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (signedMessage.accountId !== accountId) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Account ID mismatch\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst publicKey = signedMessage.publicKey;\n\n\t\t\t\t\t\tconst nonceHash = await hashNonce(nonceBytes);\n\n\t\t\t\t\t\tconst existingNonce = await ctx.context.internalAdapter.findVerificationValue(\n\t\t\t\t\t\t\t`siwn-nonce:${nonceHash}`\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (existingNonce) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Nonce already used (replay attack detected)\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t\tcode: \"UNAUTHORIZED_NONCE_REPLAY\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait ctx.context.internalAdapter.createVerificationValue({\n\t\t\t\t\t\t\tidentifier: `siwn-nonce:${nonceHash}`,\n\t\t\t\t\t\t\tvalue: \"used\",\n\t\t\t\t\t\t\texpiresAt: new Date(Date.now() + 15 * 60 * 1000),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!options.requireFullAccessKey) {\n\t\t\t\t\t\t\tconst validateKey = options.validateLimitedAccessKey\n\t\t\t\t\t\t\t\t|| ((args: { accountId: string; publicKey: string; recipient?: string }) =>\n\t\t\t\t\t\t\t\t\tdefaultValidateLimitedAccessKey(args.accountId, args.publicKey, args.recipient || getRecipient(network), near));\n\n\t\t\t\t\t\t\tconst isValidKey = await validateKey({\n\t\t\t\t\t\t\t\taccountId: accountId,\n\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\trecipient: options.recipient\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (!isValidKey) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Invalid function call access key\",\n\t\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet user: User | null = null;\n\n\t\t\t\t\t\tconst existingNearAccount: NearAccount | null =\n\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (existingNearAccount) {\n\t\t\t\t\t\t\tuser = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\tmodel: \"user\",\n\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\t\t\t\t\toperator: \"eq\",\n\t\t\t\t\t\t\t\t\t\tvalue: existingNearAccount.userId,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst anyNearAccount: NearAccount | null =\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (anyNearAccount) {\n\t\t\t\t\t\t\t\tuser = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\tmodel: \"user\",\n\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\t\t\t\t\t\toperator: \"eq\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: anyNearAccount.userId,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!user) {\n\t\t\t\t\t\t\tconst userEmail = deriveEmail(accountId) ?? \"\";\n\n\t\t\t\t\t\t\tconst profile = await (options.getProfile || ((id: AccountId) => defaultGetProfile(id, apiKey)))(accountId);\n\n\t\t\t\t\t\t\tuser = await ctx.context.internalAdapter.createUser({\n\t\t\t\t\t\t\t\tname: profile?.name ?? accountId,\n\t\t\t\t\t\t\t\temail: userEmail,\n\t\t\t\t\t\t\t\timage: profile?.image ? getImageUrl(profile.image) : \"\",\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\t\tisPrimary: true,\n\t\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tawait ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\t\tproviderId: \"siwn\",\n\t\t\t\t\t\t\t\taccountId: `${accountId}:${network}`,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (!existingNearAccount) {\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\t\t\tisPrimary: false,\n\t\t\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tawait ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\t\t\tproviderId: \"siwn\",\n\t\t\t\t\t\t\t\t\taccountId: `${accountId}:${network}`,\n\t\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait ensureRelayer(ctx.context.adapter, ctx.context.secret, network);\n\n\t\t\t\t\t\tconst session = await ctx.context.internalAdapter.createSession(\n\t\t\t\t\t\t\tuser.id\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!session) {\n\t\t\t\t\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\t\t\t\t\tmessage: \"Internal Server Error\",\n\t\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait setSessionCookie(ctx, { session, user });\n\n\t\t\t\t\t\treturn ctx.json(VerifyResponse.parse({\n\t\t\t\t\t\t\ttoken: session.token,\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tuser: {\n\t\t\t\t\t\t\t\tid: user.id,\n\t\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}));\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (error instanceof APIError) throw error;\n\t\t\t\t\t\tconst msg = error instanceof Error ? error.message : \"Unknown error\";\n\t\t\t\t\t\tconst at = error instanceof Error && error.stack ? error.stack.split(\"\\n\").slice(1, 3).map(s => s.trim()).join(\" <- \") : \"\";\n\t\t\t\t\t\tconsole.error(`[siwn] Verify error: ${msg}${at ? ` (${at})` : \"\"}`);\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Something went wrong. Please try again later.\",\n\t\t\t\t\t\t\terror: msg,\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\trelayNearTransaction: createAuthEndpoint(\n\t\t\t\t\"/near/relay\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: RelayRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { payload } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Must be authenticated to relay transactions\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!nearAccount) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"No NEAR account linked to session\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst network = nearAccount.network as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst rState = await ensureRelayer(ctx.context.adapter, ctx.context.secret, network);\n\n\t\t\t\t\tif (!rState) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Relayer not configured\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst decoded: SignedDelegateAction = decodeSignedDelegateAction(payload);\n\t\t\t\t\t\tconst delegateAction = decoded.signedDelegate.delegateAction;\n\n\t\t\t\t\t\tif (delegateAction.senderId !== nearAccount.accountId) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Delegate action sender does not match session account\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst relayerConfigForNetwork = getRelayerConfig(network);\n\t\t\t\t\t\tif (relayerConfigForNetwork?.whitelistedContracts?.length) {\n\t\t\t\t\t\t\tif (!relayerConfigForNetwork.whitelistedContracts.includes(delegateAction.receiverId)) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"FORBIDDEN\", {\n\t\t\t\t\t\t\t\t\tmessage: `Contract ${delegateAction.receiverId} is not whitelisted for relay`,\n\t\t\t\t\t\t\t\t\tstatus: 403,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (relayerConfigForNetwork?.maxGasPerTransaction) {\n\t\t\t\t\t\t\tconst totalGas = delegateAction.actions.reduce((sum: bigint, a) => {\n\t\t\t\t\t\t\t\treturn sum + (\"functionCall\" in a ? a.functionCall.gas : 0n);\n\t\t\t\t\t\t\t}, 0n);\n\t\t\t\t\t\t\tif (totalGas > BigInt(relayerConfigForNetwork.maxGasPerTransaction)) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: `Transaction gas (${totalGas}) exceeds relayer limit (${relayerConfigForNetwork.maxGasPerTransaction})`,\n\t\t\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (relayerConfigForNetwork?.maxDepositPerTransaction) {\n\t\t\t\t\t\t\tconst totalDeposit = delegateAction.actions.reduce((sum: bigint, a) => {\n\t\t\t\t\t\t\t\tif (\"functionCall\" in a) return sum + a.functionCall.deposit;\n\t\t\t\t\t\t\t\tif (\"transfer\" in a) return sum + a.transfer.deposit;\n\t\t\t\t\t\t\t\treturn sum;\n\t\t\t\t\t\t\t}, 0n);\n\t\t\t\t\t\t\tif (totalDeposit > BigInt(relayerConfigForNetwork.maxDepositPerTransaction)) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: `Transaction deposit (${totalDeposit}) exceeds relayer limit (${relayerConfigForNetwork.maxDepositPerTransaction})`,\n\t\t\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst result = await relayOnChain(payload, rState);\n\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"relayedTransaction\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\ttxHash: result.txHash,\n\t\t\t\t\t\t\t\tsenderId: delegateAction.senderId,\n\t\t\t\t\t\t\t\treceiverId: delegateAction.receiverId,\n\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (rState.mode === \"ephemeral\") {\n\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\tmodel: \"relayerKey\",\n\t\t\t\t\t\t\twhere: [{ field: \"network\", operator: \"eq\", value: network }],\n\t\t\t\t\t\t\tupdate: { lastUsedAt: new Date() },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t\treturn ctx.json(RelayResponse.parse({\n\t\t\t\t\t\t\ttxHash: result.txHash,\n\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t}));\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (error instanceof APIError) throw error;\n\t\t\t\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\t\t\t\tmessage: error instanceof Error ? error.message : \"Relay failed\",\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetRelayStatus: createAuthEndpoint(\n\t\t\t\t\"/near/relay-status/:txHash\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst txHash = (ctx.params as Record<string, string>)?.txHash;\n\t\t\t\t\tif (!txHash) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Transaction hash required\",\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tconst relayedTx = await ctx.context.adapter.findOne<RelayedTransactionRecord>({\n\t\t\t\t\t\tmodel: \"relayedTransaction\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"txHash\", operator: \"eq\", value: txHash },\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!relayedTx) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"Transaction not found or not owned by this user\",\n\t\t\t\t\t\t\tstatus: 404,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst network = relayedTx.network;\n\t\t\t\t\tconst senderId = relayedTx.senderId;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\t\tconst txResult = await near.getTransactionStatus(txHash, senderId);\n\n\t\t\t\t\t\tconst txStatus = txResult.status;\n\t\t\t\t\t\tif (txStatus && typeof txStatus === \"object\") {\n\t\t\t\t\t\t\tconst hasSuccess = \"SuccessValue\" in txStatus || \"SuccessReceiptId\" in txStatus;\n\t\t\t\t\t\t\tconst hasFailure = \"Failure\" in txStatus;\n\t\t\t\t\t\t\tconst status = hasSuccess ? \"completed\" : hasFailure ? \"failed\" : \"pending\";\n\n\t\t\t\t\t\t\tif (status !== \"pending\") {\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\t\t\tmodel: \"relayedTransaction\",\n\t\t\t\t\t\t\t\t\twhere: [{ field: \"txHash\", operator: \"eq\", value: txHash }],\n\t\t\t\t\t\t\t\t\tupdate: { status },\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst gasUsed = txResult.transaction_outcome?.outcome?.gas_burnt?.toString();\n\n\t\t\t\t\t\t\treturn ctx.json(RelayStatusResponse.parse({\n\t\t\t\t\t\t\t\tstatus,\n\t\t\t\t\t\t\t\tgasUsed,\n\t\t\t\t\t\t\t\toutcome: txResult,\n\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn ctx.json(RelayStatusResponse.parse({ status: \"pending\" }));\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\treturn ctx.json(RelayStatusResponse.parse({ status: \"pending\" }));\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetRelayerInfo: createAuthEndpoint(\n\t\t\t\t\"/near/relayer-info\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: GetRelayerInfoRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { network: requestedNetwork } = ctx.body;\n\t\t\t\t\tconst targetNetwork = (requestedNetwork ?? primaryNetwork) as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst rState = await ensureRelayer(ctx.context.adapter, ctx.context.secret, targetNetwork);\n\n\t\t\t\t\tif (!rState) {\n\t\t\t\t\t\treturn ctx.json({ enabled: false, subAccountAvailable: false } satisfies Partial<RelayerInfo> & { enabled: boolean });\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subAccountCfg = getSubAccountConfig(targetNetwork);\n\t\t\t\t\tconst { parentAccount, subAccountAvailable } = resolveParentAccount(subAccountCfg, rState);\n\n\t\t\t\t\tconst near = getNear(rState.network);\n\t\t\t\t\tlet account;\n\t\t\t\t\ttry {\n\t\t\t\t\t\taccount = await near.getAccount(rState.accountId);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\taccount = {\n\t\t\t\t\t\t\tbalance: \"0\",\n\t\t\t\t\t\t\tavailable: \"0\",\n\t\t\t\t\t\t\tstaked: \"0\",\n\t\t\t\t\t\t\tstorageUsage: \"0\",\n\t\t\t\t\t\t\tstorageBytes: 0,\n\t\t\t\t\t\t\thasContract: false,\n\t\t\t\t\t\t\tcodeHash: \"\",\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\taccountId: rState.accountId,\n\t\t\t\t\t\tmode: rState.mode,\n\t\t\t\t\t\tnetwork: rState.network,\n\t\t\t\t\t\tpublicKey: rState.publicKey,\n\t\t\t\t\t\tbalance: account.balance,\n\t\t\t\t\t\tavailable: account.available,\n\t\t\t\t\t\tstaked: account.staked,\n\t\t\t\t\t\tstorageUsage: account.storageUsage,\n\t\t\t\t\t\tstorageBytes: account.storageBytes,\n\t\t\t\t\t\thasContract: account.hasContract,\n\t\t\t\t\t\thasKey: true,\n\t\t\t\t\t\tcreatedAt: rState.createdAt,\n\t\t\t\t\t\tlastUsedAt: rState.lastUsedAt,\n\t\t\t\t\t\tparentAccount: parentAccount ?? undefined,\n\t\t\t\t\t\tsubAccountAvailable,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetRelayHistory: createAuthEndpoint(\n\t\t\t\t\"/near/relay-history\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tlet transactions: RelayedTransactionRecord[] = [];\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await ctx.context.adapter.findMany<RelayedTransactionRecord>({\n\t\t\t\t\t\t\tmodel: \"relayedTransaction\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t\ttransactions = result || [];\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error(\"relay-history findMany error:\", err);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst sorted = transactions.sort((a, b) => {\n\t\t\t\t\t\tconst aTime = a.createdAt instanceof Date ? a.createdAt.getTime() : new Date(a.createdAt ?? 0).getTime();\n\t\t\t\t\t\tconst bTime = b.createdAt instanceof Date ? b.createdAt.getTime() : new Date(b.createdAt ?? 0).getTime();\n\t\t\t\t\t\treturn bTime - aTime;\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\ttransactions: sorted.map((tx) => ({\n\t\t\t\t\t\t\tid: String(tx.id ?? \"\"),\n\t\t\t\t\t\t\tuserId: String(tx.userId ?? \"\"),\n\t\t\t\t\t\t\ttxHash: String(tx.txHash ?? \"\"),\n\t\t\t\t\t\t\tsenderId: String(tx.senderId ?? \"\"),\n\t\t\t\t\t\t\treceiverId: String(tx.receiverId ?? \"\"),\n\t\t\t\t\t\t\tnetwork: String(tx.network ?? \"mainnet\"),\n\t\t\t\t\t\t\tstatus: String(tx.status ?? \"pending\"),\n\t\t\t\t\t\t\tgasUsed: tx.gasUsed ? String(tx.gasUsed) : undefined,\n\t\t\t\t\t\t\tcreatedAt: tx.createdAt instanceof Date ? tx.createdAt.toISOString() : tx.createdAt ? String(tx.createdAt) : new Date().toISOString(),\n\t\t\t\t\t\t\tupdatedAt: tx.updatedAt instanceof Date ? tx.updatedAt.toISOString() : tx.updatedAt ? String(tx.updatedAt) : undefined,\n\t\t\t\t\t\t})),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tviewContract: createAuthEndpoint(\n\t\t\t\t\"/near/view\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: ViewContractRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { contractId, methodName, args } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tconst network = (nearAccount?.network || primaryNetwork) as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\tlet result: unknown;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresult = await near.view(contractId, methodName, args ?? {});\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (error instanceof APIError) throw error;\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: error instanceof Error ? error.message : \"Unknown error\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn ctx.json(ViewContractResponse.parse({ result }));\n\t\t\t\t},\n\t\t\t),\n\t\t\tcreateSubAccount: createAuthEndpoint(\n\t\t\t\t\"/near/create-sub-account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: CreateSubAccountRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { subAccountName, network: providedNetwork, publicKey } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Must be authenticated to create a sub-account\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tconst network = (providedNetwork || nearAccount?.network || primaryNetwork) as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst subAccountCfg = getSubAccountConfig(network);\n\t\t\t\t\tconst rState = await ensureRelayer(ctx.context.adapter, ctx.context.secret, network);\n\n\t\t\t\t\tif (!rState) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Relayer not configured — sub-account creation requires a funded relayer\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { parentAccount, subAccountAvailable } = resolveParentAccount(subAccountCfg, rState);\n\n\t\t\t\t\tif (!subAccountAvailable || !parentAccount) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Sub-account creation requires a named parent account. Configure subAccount.parentAccount in your SIWN plugin options, or use an explicit relayer with a named account.\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (parentAccount !== rState.accountId && !subAccountCfg?.parentKey) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Sub-account parent differs from relayer account. Configure subAccount.parentKey to enable signing as the parent account.\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst newAccountId = `${subAccountName}.${parentAccount}`;\n\t\t\t\t\tconst minDeposit = subAccountCfg?.minDeposit || \"0.1 NEAR\";\n\n\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\tconst exists = await near.accountExists(newAccountId);\n\t\t\t\t\tif (exists) {\n\t\t\t\t\t\tthrow new APIError(\"CONFLICT\", {\n\t\t\t\t\t\t\tmessage: `Account ${newAccountId} already exists on ${network}`,\n\t\t\t\t\t\t\tstatus: 409,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tlet txBuilder = rState.near\n\t\t\t\t\t\t.transaction(parentAccount)\n\t\t\t\t\t\t.createAccount(newAccountId)\n\t\t\t\t\t\t.addKey(publicKey, { type: \"fullAccess\" });\n\n\t\t\t\t\tif (subAccountCfg?.parentKey) {\n\t\t\t\t\t\ttxBuilder = txBuilder.signWith(subAccountCfg.parentKey as PrivateKey);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (subAccountCfg?.addRelayerFCAK !== false && subAccountCfg?.relayerFCAK) {\n\t\t\t\t\t\tconst fcakPermission: { type: \"functionCall\"; receiverId: string; methodNames?: string[]; allowance?: string } = {\n\t\t\t\t\t\t\ttype: \"functionCall\",\n\t\t\t\t\t\t\treceiverId: subAccountCfg.relayerFCAK.receiverId,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (subAccountCfg.relayerFCAK.methodNames) {\n\t\t\t\t\t\t\tfcakPermission.methodNames = subAccountCfg.relayerFCAK.methodNames;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subAccountCfg.relayerFCAK.allowance) {\n\t\t\t\t\t\t\tfcakPermission.allowance = subAccountCfg.relayerFCAK.allowance as `${number} NEAR` | `${bigint} yocto`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttxBuilder.addKey(rState.publicKey, fcakPermission as any);\n\t\t\t\t\t}\n\n\t\t\t\t\ttxBuilder.transfer(newAccountId, minDeposit as `${number} NEAR`);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait txBuilder.send({ waitUntil: \"EXECUTED\" });\n\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\taccountId: newAccountId,\n\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\tpublicKey,\n\t\t\t\t\t\t\t\tisPrimary: false,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tproviderId: \"siwn\",\n\t\t\t\t\t\t\taccountId: `${newAccountId}:${network}`,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn ctx.json(CreateSubAccountResponse.parse({\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\taccountId: newAccountId,\n\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\tpublicKey,\n\t\t\t\t\t\t\tmessage: `Sub-account ${newAccountId} created on ${network}`,\n\t\t\t\t\t\t}));\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tconst msg = error instanceof Error ? error.message : \"Unknown error\";\n\t\t\t\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\t\t\t\tmessage: `Failed to create sub-account: ${msg}`,\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tcheckSubAccountAvailability: createAuthEndpoint(\n\t\t\t\t\"/near/check-sub-account-availability\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: CheckSubAccountAvailabilityRequest,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { subAccountName, network: providedNetwork } = ctx.body;\n\n\t\t\t\t\tconst network = (providedNetwork || primaryNetwork) as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst subAccountCfg = getSubAccountConfig(network);\n\t\t\t\t\tconst rState = await ensureRelayer(ctx.context.adapter, ctx.context.secret, network);\n\n\t\t\t\t\tconst { parentAccount, subAccountAvailable } = resolveParentAccount(subAccountCfg, rState);\n\n\t\t\t\t\tif (!subAccountAvailable || !parentAccount) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Sub-account creation requires a named parent account. Configure subAccount.parentAccount in your SIWN plugin options, or use an explicit relayer with a named account.\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst accountId = `${subAccountName}.${parentAccount}`;\n\n\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\tconst exists = await near.accountExists(accountId);\n\n\t\t\t\t\treturn ctx.json(CheckSubAccountAvailabilityResponse.parse({\n\t\t\t\t\t\tavailable: !exists,\n\t\t\t\t\t\taccountId,\n\t\t\t\t\t}));\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t});\n};\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":["z"],"sources":["../src/profile.ts","../src/schema.ts","../src/types.ts","../src/utils.ts","../src/index.ts"],"sourcesContent":["import type { AccountId, Profile, SocialImage } from \"./types.js\";\n\nconst FALLBACK_URL =\n\t\"https://ipfs.near.social/ipfs/bafkreidn5fb2oygegqaldx7ycdmhu4owcrmoxd7ekbzfmeakkobz2ja7qy\";\n\nfunction getNetworkFromAccountId(accountId: string): \"mainnet\" | \"testnet\" {\n\treturn accountId.endsWith('.testnet') ? 'testnet' : 'mainnet';\n}\n\nfunction getImageUrl(\n\timage: SocialImage | undefined,\n\tfallback?: string,\n): string {\n\tif (image?.url) return image.url;\n\tif (image?.ipfs_cid) return `https://ipfs.near.social/ipfs/${image.ipfs_cid}`;\n\treturn fallback || FALLBACK_URL;\n}\n\ninterface SocialApiResponse {\n\t[accountId: string]: {\n\t\tprofile?: Profile;\n\t};\n}\n\ninterface KvEntry {\n\tvalue: Record<string, unknown> | string;\n\tblock_height?: number;\n\tblock_hash?: string;\n\ttimestamp_nanosec?: string;\n}\n\ninterface KvResponse {\n\tentries: KvEntry[];\n}\n\nasync function defaultGetProfile(accountId: AccountId, apiKey?: string): Promise<Profile | null> {\n\tconst network = getNetworkFromAccountId(accountId);\n\n\ttry {\n\t\tconst kvUrl = network === \"testnet\"\n\t\t\t? \"https://kv.test.fastnear.com\"\n\t\t\t: \"https://kv.main.fastnear.com\";\n\n\t\tconst effectiveApiKey = apiKey || process.env.FASTNEAR_API_KEY;\n\t\tconst headers: Record<string, string> = { \"Content-Type\": \"application/json\" };\n\t\tif (effectiveApiKey) {\n\t\t\theaders[\"Authorization\"] = `Bearer ${effectiveApiKey}`;\n\t\t}\n\n\t\tconst response = await fetch(\n\t\t\t`${kvUrl}/v0/latest/social.near/${accountId}/profile/**`,\n\t\t\t{ headers },\n\t\t);\n\n\t\tif (response.ok) {\n\t\t\tconst data = await response.json() as KvResponse;\n\t\t\tconst entry = data?.entries?.[0];\n\t\t\tif (entry?.value) {\n\t\t\t\ttry {\n\t\t\t\t\tconst profile = typeof entry.value === \"string\"\n\t\t\t\t\t\t? JSON.parse(entry.value)\n\t\t\t\t\t\t: entry.value;\n\t\t\t\t\tif (profile?.name || profile?.description || profile?.image) {\n\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\tname: profile.name,\n\t\t\t\t\t\t\tdescription: profile.description,\n\t\t\t\t\t\t\timage: profile.image,\n\t\t\t\t\t\t\tbackgroundImage: profile.backgroundImage,\n\t\t\t\t\t\t\tlinktree: profile.linktree,\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\t\t\t\t} catch {}\n\t\t\t}\n\t\t}\n\n\t\tconst apiBase = {\n\t\t\tmainnet: \"https://api.near.social\",\n\t\t\ttestnet: \"https://test.api.near.social\",\n\t\t}[network];\n\n\t\tconst keys = [`${accountId}/profile/**`];\n\n\t\tconst fallbackResponse = await fetch(`${apiBase}/get`, {\n\t\t\tmethod: \"POST\",\n\t\t\theaders: { \"Content-Type\": \"application/json\" },\n\t\t\tbody: JSON.stringify({ keys })\n\t\t});\n\n\t\tif (!fallbackResponse.ok) {\n\t\t\tthrow new Error(`HTTP error! status: ${fallbackResponse.status}`);\n\t\t}\n\n\t\tconst fallbackData = await fallbackResponse.json() as SocialApiResponse;\n\t\tconst profile: Profile | undefined = fallbackData?.[accountId]?.profile;\n\n\t\tif (profile) {\n\t\t\treturn {\n\t\t\t\tname: profile.name,\n\t\t\t\tdescription: profile.description,\n\t\t\t\timage: profile.image,\n\t\t\t\tbackgroundImage: profile.backgroundImage,\n\t\t\t\tlinktree: profile.linktree\n\t\t\t};\n\t\t}\n\t\treturn null;\n\t} catch (error) {\n\t\treturn null;\n\t}\n}\n\nexport { defaultGetProfile, getImageUrl, getNetworkFromAccountId };\n","import type { BetterAuthPluginDBSchema } from \"better-auth/db\";\n\nexport const schema = {\n\tnearAccount: {\n\t\tfields: {\n\t\t\tuserId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\treferences: {\n\t\t\t\t\tmodel: \"user\",\n\t\t\t\t\tfield: \"id\",\n\t\t\t\t},\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\taccountId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tnetwork: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tpublicKey: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tisPrimary: {\n\t\t\t\ttype: \"boolean\",\n\t\t\t\tdefaultValue: false,\n\t\t\t},\n\t\t\tcreatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t},\n\t},\n\trelayedTransaction: {\n\t\tfields: {\n\t\t\tuserId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\treferences: {\n\t\t\t\t\tmodel: \"user\",\n\t\t\t\t\tfield: \"id\",\n\t\t\t\t},\n\t\t\t},\n\t\t\ttxHash: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tsenderId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\treceiverId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tnetwork: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tstatus: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tgasUsed: {\n\t\t\t\ttype: \"string\",\n\t\t\t},\n\t\t\tcreatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tupdatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t},\n\t\t},\n\t},\n\trelayerKey: {\n\t\tfields: {\n\t\t\taccountId: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tencryptedPrivateKey: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tiv: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tpublicKey: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tnetwork: {\n\t\t\t\ttype: \"string\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tcreatedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t\trequired: true,\n\t\t\t},\n\t\t\tlastUsedAt: {\n\t\t\t\ttype: \"date\",\n\t\t\t},\n\t\t},\n\t},\n} satisfies BetterAuthPluginDBSchema;\n","import { z } from \"zod\";\nimport { AccountIdSchema, type AccountId } from \"near-kit/schemas\";\nimport type { AccountState } from \"near-kit\";\n\nexport type { AccountId };\n\nexport interface NearAccount {\n\tid: string;\n\tuserId: string;\n\taccountId: string;\n\tnetwork: \"mainnet\" | \"testnet\";\n\tpublicKey: string;\n\tisPrimary: boolean;\n\tcreatedAt: Date;\n}\n\nexport interface ListedNearAccount extends NearAccount {\n\tproviderId: \"siwn\";\n\tisActive: boolean;\n\tisAvailable: boolean;\n}\n\nexport interface ListAccountsResponseT {\n\taccounts: ListedNearAccount[];\n\tactiveAccount: ListedNearAccount | null;\n\tavailableAccounts: ListedNearAccount[];\n}\n\nexport interface SetPrimaryAccountResponseT extends ListAccountsResponseT {\n\tsuccess: boolean;\n\taccountId: string;\n\tnetwork: \"mainnet\" | \"testnet\";\n\tmessage: string;\n}\n\nexport const socialImageSchema = z.object({\n\turl: z.string().optional(),\n\tipfs_cid: z.string().optional(),\n});\n\nexport const profileSchema = z.object({\n\tname: z.string().optional(),\n\tdescription: z.string().optional(),\n\timage: socialImageSchema.optional(),\n\tbackgroundImage: socialImageSchema.optional(),\n\tlinktree: z.record(z.string(), z.string()).optional(),\n});\n\nexport type SocialImage = z.infer<typeof socialImageSchema>;\nexport type Profile = z.infer<typeof profileSchema>;\n\nconst signedMessageSchema = z.object({\n\taccountId: z.string(),\n\tpublicKey: z.string(),\n\tsignature: z.string(),\n\tstate: z.string().optional(),\n});\n\nexport const LinkAccountRequest = z.object({\n\tsignedMessage: signedMessageSchema,\n\tmessage: z.string(),\n\trecipient: z.string(),\n\tnonce: z.string(),\n\taccountId: AccountIdSchema,\n});\n\nexport const SetPrimaryAccountRequest = z.object({\n\taccountId: AccountIdSchema,\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n});\n\nexport const NonceRequest = z.object({\n\taccountId: AccountIdSchema,\n\tnetworkId: z.union([z.literal(\"mainnet\"), z.literal(\"testnet\")])\n});\n\nexport const VerifyRequest = z.object({\n\tsignedMessage: signedMessageSchema,\n\tmessage: z.string(),\n\trecipient: z.string(),\n\tnonce: z.string(),\n\taccountId: AccountIdSchema,\n});\n\nexport const RelayRequest = z.object({\n\tpayload: z.string(),\n});\nexport type RelayRequestT = z.infer<typeof RelayRequest>;\n\nexport const RelayResponse = z.object({\n\ttxHash: z.string(),\n\tstatus: z.enum([\"pending\", \"completed\", \"failed\"]),\n});\nexport type RelayResponseT = z.infer<typeof RelayResponse>;\n\nexport const RelayStatusResponse = z.object({\n\tstatus: z.enum([\"pending\", \"completed\", \"failed\"]),\n\tgasUsed: z.string().optional(),\n\toutcome: z.unknown().optional(),\n});\nexport type RelayStatusResponseT = z.infer<typeof RelayStatusResponse>;\n\nexport const ViewContractRequest = z.object({\n\tcontractId: z.string(),\n\tmethodName: z.string(),\n\targs: z.record(z.string(), z.any()).optional(),\n});\nexport type ViewContractRequestT = z.infer<typeof ViewContractRequest>;\n\nexport const NonceResponse = z.object({ nonce: z.string() });\nexport const VerifyResponse = z.object({\n\ttoken: z.string(),\n\tsuccess: z.literal(true),\n\tuser: z.object({\n\t\tid: z.string(),\n\t\taccountId: AccountIdSchema,\n\t\tnetwork: z.union([z.literal(\"mainnet\"), z.literal(\"testnet\")]),\n\t}),\n});\nexport const ProfileResponse = profileSchema.nullable();\nexport const ViewContractResponse = z.object({ result: z.unknown() });\n\nexport const ProfileRequest = z.object({\n\taccountId: AccountIdSchema.optional(),\n});\nexport type ProfileRequestT = z.infer<typeof ProfileRequest>;\n\nexport type NonceRequestT = z.infer<typeof NonceRequest>;\nexport type NonceResponseT = z.infer<typeof NonceResponse>;\nexport type SetPrimaryAccountRequestT = z.infer<typeof SetPrimaryAccountRequest>;\nexport type VerifyRequestT = z.infer<typeof VerifyRequest>;\nexport type VerifyResponseT = z.infer<typeof VerifyResponse>;\nexport type ProfileResponseT = z.infer<typeof ProfileResponse>;\nexport type ViewContractResponseT = z.infer<typeof ViewContractResponse>;\n\nexport const RelayedTransactionSchema = z.object({\n\tid: z.string(),\n\tuserId: z.string(),\n\ttxHash: z.string(),\n\tsenderId: z.string(),\n\treceiverId: z.string(),\n\tnetwork: z.string(),\n\tstatus: z.string(),\n\tgasUsed: z.string().optional(),\n\tcreatedAt: z.string(),\n\tupdatedAt: z.string().optional(),\n});\nexport type RelayedTransactionT = z.infer<typeof RelayedTransactionSchema>;\n\nexport const RelayHistoryResponse = z.object({\n\ttransactions: z.array(RelayedTransactionSchema),\n});\nexport type RelayHistoryResponseT = z.infer<typeof RelayHistoryResponse>;\n\nexport interface RelayedTransactionRecord {\n\tid: string;\n\tuserId: string;\n\ttxHash: string;\n\tsenderId: string;\n\treceiverId: string;\n\tnetwork: \"mainnet\" | \"testnet\";\n\tstatus: string;\n\tgasUsed?: string;\n\tcreatedAt: Date;\n\tupdatedAt: Date;\n}\n\nexport interface RelayerInfo extends AccountState {\n\taccountId: string;\n\tmode: \"ephemeral\" | \"explicit\";\n\tnetwork: \"mainnet\" | \"testnet\";\n\tpublicKey: string;\n\thasKey: boolean;\n\tcreatedAt?: Date;\n\tlastUsedAt?: Date;\n\tparentAccount?: string;\n\tsubAccountAvailable?: boolean;\n}\n\nexport interface DualNetworkConfig<T> {\n\tmainnet: T;\n\ttestnet: T;\n}\n\nexport const GetRelayerInfoRequest = z.object({\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n});\nexport type GetRelayerInfoRequestT = z.infer<typeof GetRelayerInfoRequest>;\n\nexport interface SubAccountRelayerFCAKConfig {\n\treceiverId: string;\n\tmethodNames?: string[];\n\tallowance?: string;\n}\n\nexport interface SubAccountConfig {\n\tparentAccount?: string;\n\tparentKey?: string;\n\tminDeposit?: string;\n\taddRelayerFCAK?: boolean;\n\trelayerFCAK?: SubAccountRelayerFCAKConfig;\n}\n\nexport const CreateSubAccountRequest = z.object({\n\tsubAccountName: z.string().regex(/^[a-z0-9]+$/, \"Must be lowercase alphanumeric characters only\"),\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n\tpublicKey: z.string(),\n});\nexport type CreateSubAccountRequestT = z.infer<typeof CreateSubAccountRequest>;\n\nexport const CreateSubAccountResponse = z.object({\n\tsuccess: z.literal(true),\n\taccountId: z.string(),\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]),\n\tpublicKey: z.string(),\n\tmessage: z.string(),\n});\nexport type CreateSubAccountResponseT = z.infer<typeof CreateSubAccountResponse>;\n\nexport const CheckSubAccountAvailabilityRequest = z.object({\n\tsubAccountName: z.string().regex(/^[a-z0-9]+$/),\n\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n});\nexport type CheckSubAccountAvailabilityRequestT = z.infer<typeof CheckSubAccountAvailabilityRequest>;\n\nexport const CheckSubAccountAvailabilityResponse = z.object({\n\tavailable: z.boolean(),\n\taccountId: z.string(),\n});\nexport type CheckSubAccountAvailabilityResponseT = z.infer<typeof CheckSubAccountAvailabilityResponse>;\n","export function bytesToBase64(bytes: Uint8Array): string {\n\treturn btoa(String.fromCharCode(...bytes));\n}\n\nfunction base64ToBytes(base64: string): Uint8Array {\n\treturn Uint8Array.from(atob(base64), c => c.charCodeAt(0));\n}\n\nexport function bytesToHex(bytes: Uint8Array): string {\n\treturn Array.from(bytes).map(b => b.toString(16).padStart(2, \"0\")).join(\"\");\n}\n\nexport function hexToBytes(hex: string): Uint8Array {\n\tconst bytes = new Uint8Array(hex.length / 2);\n\tfor (let i = 0; i < hex.length; i += 2) {\n\t\tbytes[i / 2] = parseInt(hex.substring(i, i + 2), 16);\n\t}\n\treturn bytes;\n}\n\nasync function deriveAesKey(secret: string): Promise<CryptoKey> {\n\tconst keyMaterial = await crypto.subtle.importKey(\n\t\t\"raw\",\n\t\tnew TextEncoder().encode(secret),\n\t\t{ name: \"HKDF\" },\n\t\tfalse,\n\t\t[\"deriveKey\"],\n\t);\n\treturn crypto.subtle.deriveKey(\n\t\t{\n\t\t\tname: \"HKDF\",\n\t\t\thash: \"SHA-256\",\n\t\t\tsalt: new TextEncoder().encode(\"better-near-auth-relayer\"),\n\t\t\tinfo: new Uint8Array(0),\n\t\t},\n\t\tkeyMaterial,\n\t\t{ name: \"AES-GCM\", length: 256 },\n\t\tfalse,\n\t\t[\"encrypt\", \"decrypt\"],\n\t);\n}\n\nexport async function encryptPrivateKey(\n\tprivateKey: Uint8Array,\n\tsecret: string,\n): Promise<{ encrypted: string; iv: string }> {\n\tconst aesKey = await deriveAesKey(secret);\n\tconst iv = crypto.getRandomValues(new Uint8Array(12));\n\tconst encrypted = await crypto.subtle.encrypt(\n\t\t{ name: \"AES-GCM\", iv },\n\t\taesKey,\n\t\tprivateKey as Uint8Array<ArrayBuffer>,\n\t);\n\treturn {\n\t\tencrypted: bytesToBase64(new Uint8Array(encrypted)),\n\t\tiv: bytesToBase64(iv),\n\t};\n}\n\nexport async function decryptPrivateKey(\n\tencrypted: string,\n\tiv: string,\n\tsecret: string,\n): Promise<Uint8Array> {\n\tconst aesKey = await deriveAesKey(secret);\n\tconst decrypted = await crypto.subtle.decrypt(\n\t\t{ name: \"AES-GCM\", iv: base64ToBytes(iv) as Uint8Array<ArrayBuffer> },\n\t\taesKey,\n\t\tbase64ToBytes(encrypted) as Uint8Array<ArrayBuffer>,\n\t);\n\treturn new Uint8Array(decrypted);\n}\n","import { APIError, createAuthEndpoint, createAuthMiddleware, sessionMiddleware } from \"better-auth/api\";\nimport { setSessionCookie } from \"better-auth/cookies\";\nimport type { Account, User, DBAdapter } from \"better-auth/types\";\n// Explicit type imports for declaration emit\nimport type {} from \"@better-auth/core/env\";\nimport type {} from \"@better-auth/core/oauth2\";\nimport type {} from \"better-call\";\n\nimport { Near, generateNonce, generateKey, parseKey, verifyNep413Signature, decodeSignedDelegateAction, InMemoryKeyStore, RotatingKeyStore } from \"near-kit\";\nimport type { SignedDelegateAction, PrivateKey } from \"near-kit\";\nimport { hex, base58 } from \"@scure/base\";\nimport z from \"zod\";\nimport { defaultGetProfile, getImageUrl, getNetworkFromAccountId } from \"./profile.js\";\nimport { schema } from \"./schema.js\";\nimport {\n\ttype AccountId,\n\ttype DualNetworkConfig,\n\ttype ListAccountsResponseT,\n\ttype ListedNearAccount,\n\ttype NearAccount,\n\ttype Profile,\n\ttype RelayerInfo,\n\ttype RelayedTransactionRecord,\n\ttype SubAccountConfig,\n\tLinkAccountRequest,\n\tNonceRequest,\n\tNonceResponse,\n\tProfileRequest,\n\tProfileResponse,\n\tVerifyRequest,\n\tVerifyResponse,\n\tRelayRequest,\n\tRelayResponse,\n\tRelayStatusResponse,\n\tSetPrimaryAccountRequest,\n\tViewContractRequest,\n\tViewContractResponse,\n\tGetRelayerInfoRequest,\n\tCreateSubAccountRequest,\n\tCreateSubAccountResponse,\n\tCheckSubAccountAvailabilityRequest,\n\tCheckSubAccountAvailabilityResponse,\n} from \"./types.js\";\nexport * from \"./types.js\";\nimport {\n\tbytesToHex,\n\tencryptPrivateKey,\n\tdecryptPrivateKey,\n} from \"./utils.js\";\n\nasync function hashNonce(nonce: Uint8Array): Promise<string> {\n\tconst data = new TextEncoder().encode(hex.encode(nonce));\n\tconst hashBuffer = await crypto.subtle.digest('SHA-256', data);\n\treturn hex.encode(new Uint8Array(hashBuffer));\n}\n\nfunction deriveEmail(accountId: string, recipient: string): string {\n\tif (accountId.endsWith(\".near\")) {\n\t\tconst localPart = accountId.slice(0, -5);\n\t\tif (!localPart.includes(\".\")) {\n\t\t\treturn `${localPart}@near.email`;\n\t\t}\n\t}\n\tconst randomId = crypto.randomUUID().slice(0, 8);\n\treturn `temp-${randomId}@${recipient}`;\n}\n\nfunction nearAccountKey(account: Pick<NearAccount, \"accountId\" | \"network\">): string {\n\treturn `${account.accountId}:${account.network}`;\n}\n\nfunction getCreatedAtTime(account: NearAccount): number {\n\treturn account.createdAt instanceof Date\n\t\t? account.createdAt.getTime()\n\t\t: new Date(account.createdAt).getTime();\n}\n\nfunction buildListAccountsResponse(nearAccounts: NearAccount[]): ListAccountsResponseT {\n\tconst activeAccount = nearAccounts.find((account) => account.isPrimary) ?? nearAccounts[0] ?? null;\n\tconst activeKey = activeAccount ? nearAccountKey(activeAccount) : null;\n\tconst accounts: ListedNearAccount[] = nearAccounts\n\t\t.map((account) => {\n\t\t\tconst isActive = activeKey === nearAccountKey(account);\n\t\t\treturn {\n\t\t\t\t...account,\n\t\t\t\tproviderId: \"siwn\" as const,\n\t\t\t\tisActive,\n\t\t\t\tisAvailable: !isActive,\n\t\t\t};\n\t\t})\n\t\t.sort((a, b) => {\n\t\t\tif (a.isActive !== b.isActive) return a.isActive ? -1 : 1;\n\t\t\treturn getCreatedAtTime(a) - getCreatedAtTime(b);\n\t\t});\n\tconst listedActiveAccount = accounts.find((account) => account.isActive) ?? null;\n\n\treturn {\n\t\taccounts,\n\t\tactiveAccount: listedActiveAccount ? { ...listedActiveAccount } : null,\n\t\tavailableAccounts: accounts\n\t\t\t.filter((account) => account.isAvailable)\n\t\t\t.map((account) => ({ ...account })),\n\t};\n}\n\nexport interface RelayerConfig {\n\taccountId?: string;\n\tprivateKey?: string;\n\tprivateKeys?: string[];\n\twhitelistedContracts?: string[];\n\tmaxGasPerTransaction?: string;\n\tmaxDepositPerTransaction?: string;\n}\n\ninterface RelayerState {\n\tnear: Near;\n\taccountId: string;\n\tnetwork: \"mainnet\" | \"testnet\";\n\tmode: \"ephemeral\" | \"explicit\";\n\tpublicKey: string;\n\tcreatedAt?: Date;\n\tlastUsedAt?: Date;\n}\n\nfunction createNear(\n\tnetwork: \"mainnet\" | \"testnet\",\n\theaders: Record<string, string>,\n\trpcUrl?: string,\n\tkeyStore?: InMemoryKeyStore | RotatingKeyStore,\n): Near {\n\tconst config: ConstructorParameters<typeof Near>[0] = { headers };\n\tif (rpcUrl) {\n\t\tconfig.network = { rpcUrl, networkId: network };\n\t} else {\n\t\tconfig.network = network;\n\t}\n\tif (keyStore) {\n\t\tconfig.keyStore = keyStore;\n\t}\n\treturn new Near(config);\n}\n\nasync function initRelayer(\n\trelayerConfig: RelayerConfig | undefined,\n\tnetwork: \"mainnet\" | \"testnet\",\n\tadapter: DBAdapter,\n\tsecret: string | undefined,\n\tapiKey?: string,\n\trpcUrl?: string,\n): Promise<RelayerState | null> {\n\tif (!relayerConfig) return null;\n\n\tconst headers: Record<string, string> = {};\n\tif (apiKey) {\n\t\theaders[\"Authorization\"] = `Bearer ${apiKey}`;\n\t}\n\n\tif (relayerConfig.accountId && (relayerConfig.privateKey || relayerConfig.privateKeys)) {\n\t\tconst keys = relayerConfig.privateKeys ?? (relayerConfig.privateKey ? [relayerConfig.privateKey] : []);\n\t\tlet keyStore: InMemoryKeyStore | RotatingKeyStore;\n\n\t\tif (keys.length === 1) {\n\t\t\tkeyStore = new InMemoryKeyStore({\n\t\t\t\t[relayerConfig.accountId]: keys[0]!,\n\t\t\t});\n\t\t} else {\n\t\t\tkeyStore = new RotatingKeyStore({\n\t\t\t\t[relayerConfig.accountId]: keys as string[],\n\t\t\t});\n\t\t}\n\n\t\tconst near = createNear(network, headers, rpcUrl, keyStore);\n\t\tconst explicitPublicKey = parseKey(keys[0]!);\n\t\treturn {\n\t\t\tnear,\n\t\t\taccountId: relayerConfig.accountId,\n\t\t\tnetwork,\n\t\t\tmode: \"explicit\",\n\t\t\tpublicKey: explicitPublicKey.publicKey.toString(),\n\t\t};\n\t}\n\n\tconst existing = await adapter.findOne<{ encryptedPrivateKey: string; iv: string; createdAt: Date; lastUsedAt: Date }>({\n\t\tmodel: \"relayerKey\",\n\t\twhere: [{ field: \"network\", operator: \"eq\", value: network }],\n\t});\n\n\tif (existing) {\n\t\tif (!secret) throw new Error(\"BETTER_AUTH_SECRET required for relayer key decryption\");\n\t\tconst privateKeyBytes = await decryptPrivateKey(existing.encryptedPrivateKey, existing.iv, secret);\n\t\tconst keyPair = parseKey(`ed25519:${base58.encode(privateKeyBytes)}`);\n\t\tconst accountId = bytesToHex(keyPair.publicKey.data);\n\n\t\tconsole.log(`[siwn] Relayer recovered: ${accountId} (${network})`);\n\n\t\tconst keyStore = new InMemoryKeyStore();\n\t\tawait keyStore.add(accountId, keyPair);\n\n\t\tconst near = createNear(network, headers, rpcUrl, keyStore);\n\t\treturn {\n\t\t\tnear,\n\t\t\taccountId,\n\t\t\tnetwork,\n\t\t\tmode: \"ephemeral\",\n\t\t\tpublicKey: keyPair.publicKey.toString(),\n\t\t\tcreatedAt: existing.createdAt,\n\t\t\tlastUsedAt: existing.lastUsedAt,\n\t\t};\n\t}\n\n\tconst keyPair = generateKey();\n\tif (!secret) throw new Error(\"BETTER_AUTH_SECRET required for relayer key encryption\");\n\tconst privateKeyBytes = keyPair.secretKey.startsWith(\"ed25519:\")\n\t\t? base58.decode(keyPair.secretKey.slice(8))\n\t\t: new Uint8Array(0);\n\n\tconst publicKeyBase58 = keyPair.publicKey.toString().replace(\"ed25519:\", \"\");\n\tconst accountId = bytesToHex(keyPair.publicKey.data);\n\tconst createdAt = new Date();\n\n\tconst { encrypted, iv } = await encryptPrivateKey(privateKeyBytes, secret);\n\n\tawait adapter.create({\n\t\t\tmodel: \"relayerKey\",\n\t\t\tdata: {\n\t\t\t\taccountId,\n\t\t\t\tencryptedPrivateKey: encrypted,\n\t\t\t\tiv,\n\t\t\t\tpublicKey: `ed25519:${publicKeyBase58}`,\n\t\t\t\tnetwork,\n\t\t\t\tcreatedAt,\n\t\t\t\tlastUsedAt: createdAt,\n\t\t\t},\n\t\t});\n\n\tconsole.log(`[siwn] Relayer created in EPHEMERAL mode: ${accountId} (${network})`);\n\tconsole.log(`[siwn] Fund this account with NEAR to enable gasless relay`);\n\tconsole.log(`[siwn] Private key is encrypted in DB — persists across restarts`);\n\n\tconst keyStore = new InMemoryKeyStore();\n\tawait keyStore.add(accountId, keyPair);\n\n\tconst near = createNear(network, headers, rpcUrl, keyStore);\n\treturn {\n\t\tnear,\n\t\taccountId,\n\t\tnetwork,\n\t\tmode: \"ephemeral\",\n\t\tpublicKey: keyPair.publicKey.toString(),\n\t\tcreatedAt,\n\t\tlastUsedAt: createdAt,\n\t};\n}\n\nasync function relayOnChain(\n\tpayload: string,\n\trelayerState: RelayerState,\n): Promise<{ txHash: string }> {\n\tconst userAction = decodeSignedDelegateAction(payload);\n\n\tconst result = await relayerState.near\n\t\t.transaction(relayerState.accountId)\n\t\t.signedDelegateAction(userAction)\n\t\t.send({ waitUntil: \"EXECUTED\" });\n\n\treturn { txHash: result.transaction.hash };\n}\n\nasync function defaultValidateLimitedAccessKey(\n\taccountId: string,\n\tpublicKey: string,\n\trecipient: string,\n\tnear: Near,\n): Promise<boolean> {\n\tconst key = await near.getAccessKey(accountId, publicKey);\n\tif (!key) return false;\n\tif (key.permission === \"FullAccess\") return true;\n\tif (\"FunctionCall\" in key.permission) {\n\t\treturn key.permission.FunctionCall.receiver_id === recipient;\n\t}\n\treturn false;\n}\n\nfunction isImplicitAccount(accountId: string): boolean {\n\treturn /^[0-9a-f]{64}$/.test(accountId);\n}\n\nfunction resolveParentAccount(\n\tsubAccountCfg: SubAccountConfig | undefined,\n\trState: RelayerState | null,\n): { parentAccount: string | null; subAccountAvailable: boolean } {\n\tif (!rState) return { parentAccount: null, subAccountAvailable: false };\n\tconst parent = subAccountCfg?.parentAccount ?? rState.accountId;\n\tif (!parent || isImplicitAccount(parent)) {\n\t\treturn { parentAccount: null, subAccountAvailable: false };\n\t}\n\treturn { parentAccount: parent, subAccountAvailable: true };\n}\n\nexport interface SIWNPluginOptions {\n\trecipient?: string;\n\trecipients?: DualNetworkConfig<string>;\n\trequireFullAccessKey?: boolean;\n\tgetNonce?: () => Promise<Uint8Array>;\n\tgetProfile?: (accountId: AccountId) => Promise<Profile | null>;\n\tvalidateLimitedAccessKey?: (args: {\n\t\taccountId: AccountId;\n\t\tpublicKey: string;\n\t\trecipient?: string;\n\t}) => Promise<boolean>;\n\tapiKey?: string;\n\trpcUrl?: string | DualNetworkConfig<string>;\n\trelayer?: RelayerConfig | DualNetworkConfig<RelayerConfig>;\n\tsubAccount?: SubAccountConfig | DualNetworkConfig<SubAccountConfig>;\n}\n\nexport const siwn = (options: SIWNPluginOptions) => {\n\tif (!options.recipient && !options.recipients) {\n\t\tthrow new Error(\"Either 'recipient' or 'recipients' must be provided to siwn plugin\");\n\t}\n\n\tconst apiKey = options.apiKey;\n\n\tconst getRecipient = (network: \"mainnet\" | \"testnet\"): string => {\n\t\tif (options.recipients) return options.recipients[network];\n\t\treturn options.recipient!;\n\t};\n\n\tconst getSupportedNetworks = (): (\"mainnet\" | \"testnet\")[] => {\n\t\tif (options.recipients) return [\"mainnet\", \"testnet\"];\n\t\tif (options.recipient) return [getNetworkFromAccountId(options.recipient)];\n\t\treturn [\"mainnet\"];\n\t};\n\n\tconst getRelayerConfig = (network: \"mainnet\" | \"testnet\"): RelayerConfig | undefined => {\n\t\tif (!options.relayer) return undefined;\n\t\tif (\"mainnet\" in options.relayer && typeof options.relayer.mainnet === \"object\") {\n\t\t\treturn (options.relayer as DualNetworkConfig<RelayerConfig>)[network];\n\t\t}\n\t\treturn options.relayer as RelayerConfig;\n\t};\n\n\tconst getRpcUrl = (network: \"mainnet\" | \"testnet\"): string | undefined => {\n\t\tif (!options.rpcUrl) return undefined;\n\t\tif (typeof options.rpcUrl === \"object\") return (options.rpcUrl as DualNetworkConfig<string>)[network];\n\t\treturn options.rpcUrl as string;\n\t};\n\n\tconst getSubAccountConfig = (network: \"mainnet\" | \"testnet\"): SubAccountConfig | undefined => {\n\t\tif (!options.subAccount) return undefined;\n\t\tif (\"mainnet\" in options.subAccount && typeof options.subAccount.mainnet === \"object\") {\n\t\t\treturn (options.subAccount as DualNetworkConfig<SubAccountConfig>)[network];\n\t\t}\n\t\treturn options.subAccount as SubAccountConfig;\n\t};\n\n\tconst primaryNetwork = getSupportedNetworks()[0];\n\tconst relayerStates = new Map<\"mainnet\" | \"testnet\", RelayerState | null>();\n\tconst relayerInitPromises = new Map<\"mainnet\" | \"testnet\", Promise<RelayerState | null>>();\n\n\tconst headers: Record<string, string> = {};\n\tif (apiKey) {\n\t\theaders[\"Authorization\"] = `Bearer ${apiKey}`;\n\t}\n\n\tconst ensureRelayer = async (adapter: DBAdapter, secret: string | undefined, network: \"mainnet\" | \"testnet\") => {\n\t\tif (relayerStates.has(network)) return relayerStates.get(network) ?? null;\n\n\t\tconst existingInit = relayerInitPromises.get(network);\n\t\tif (existingInit) return existingInit;\n\n\t\tconst relayerCfg = getRelayerConfig(network);\n\t\tconst networkRpcUrl = getRpcUrl(network);\n\n\t\tconst initPromise = initRelayer(relayerCfg, network, adapter, secret, apiKey, networkRpcUrl)\n\t\t\t.then((state) => {\n\t\t\t\trelayerStates.set(network, state);\n\t\t\t\trelayerInitPromises.delete(network);\n\t\t\t\treturn state;\n\t\t\t})\n\t\t\t.catch((error) => {\n\t\t\t\trelayerInitPromises.delete(network);\n\t\t\t\tthrow error;\n\t\t\t});\n\n\t\trelayerInitPromises.set(network, initPromise);\n\t\treturn initPromise;\n\t};\n\n\tconst getNear = (network: \"mainnet\" | \"testnet\") => {\n\t\tconst networkRpcUrl = getRpcUrl(network);\n\t\tif (networkRpcUrl) {\n\t\t\treturn new Near({ network: { rpcUrl: networkRpcUrl, networkId: network }, headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined });\n\t\t}\n\t\treturn new Near({ network, headers: apiKey ? { Authorization: `Bearer ${apiKey}` } : undefined });\n\t};\n\n\treturn ({\n\t\tid: \"siwn\",\n\t\tschema,\n\t\thooks: {\n\t\t\tafter: [\n\t\t\t\t{\n\t\t\t\t\tmatcher: (context: { path?: string; method?: string }) => context.path === \"/auth/session\" && context.method === \"GET\",\n\t\t\t\t\thandler: createAuthMiddleware(async (ctx) => {\n\t\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\t\tif (session) {\n\t\t\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (nearAccount) {\n\t\t\t\t\t\t\t\tctx.context.session = {\n\t\t\t\t\t\t\t\t\t...session,\n\t\t\t\t\t\t\t\t\tuser: {\n\t\t\t\t\t\t\t\t\t\t...session.user,\n\t\t\t\t\t\t\t\t\t\tnearAccount: nearAccount\n\t\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t\t};\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn { context: ctx };\n\t\t\t\t\t}),\n\t\t\t\t},\n\t\t\t],\n\t\t},\n\t\tendpoints: {\n\t\t\tlinkNearAccount: createAuthEndpoint(\n\t\t\t\t\"/near/link-account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: LinkAccountRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t\trequireRequest: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { signedMessage, message, recipient, nonce, accountId } = ctx.body;\n\t\t\t\t\tconst network = getNetworkFromAccountId(accountId);\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Must be logged in to link NEAR account\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\t\tconst nonceBytes = hex.decode(nonce);\n\n\t\t\t\t\t\tconst isValid = await verifyNep413Signature(\n\t\t\t\t\t\tsignedMessage,\n\t\t\t\t\t\t{ message, recipient, nonce: nonceBytes },\n\t\t\t\t\t\t\t{ near, maxAge: 15 * 60 * 1000 },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Invalid signature\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (signedMessage.accountId !== accountId) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Account ID mismatch\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst publicKey = signedMessage.publicKey;\n\n\t\t\t\t\t\tif (!options.requireFullAccessKey && options.validateLimitedAccessKey) {\n\t\t\t\t\t\t\tconst isValidKey = await options.validateLimitedAccessKey({\n\t\t\t\t\t\t\t\taccountId: accountId,\n\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\trecipient: options.recipient\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (!isValidKey) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Invalid function call access key\",\n\t\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst existingNearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (existingNearAccount) {\n\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\tmessage: \"This NEAR account is already linked to another user\",\n\t\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst existingPrimaryAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\tisPrimary: !existingPrimaryAccount,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tproviderId: \"siwn\",\n\t\t\t\t\t\t\taccountId: `${accountId}:${network}`,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\tmessage: \"NEAR account successfully linked\"\n\t\t\t\t\t\t});\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (error instanceof APIError) throw error;\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Something went wrong. Please try again later.\",\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : \"Unknown error\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tunlinkNearAccount: createAuthEndpoint(\n\t\t\t\t\"/near/unlink-account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: z.object({\n\t\t\t\t\t\taccountId: z.string(),\n\t\t\t\t\t\tnetwork: z.enum([\"mainnet\", \"testnet\"]).optional(),\n\t\t\t\t\t}),\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { accountId, network: providedNetwork } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Must be logged in to unlink NEAR account\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst network = providedNetwork || getNetworkFromAccountId(accountId);\n\n\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!nearAccount) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"NEAR account not found or not linked to your user\",\n\t\t\t\t\t\t\tstatus: 404,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst accounts = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"account\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", operator: \"eq\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (accounts.length <= 1) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Cannot unlink last authentication method. Link another account first.\",\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (nearAccount.isPrimary) {\n\t\t\t\t\t\tconst otherNearAccounts: NearAccount[] = await ctx.context.adapter.findMany({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"ne\", value: accountId },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (otherNearAccounts.length > 0) {\n\t\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t{ field: \"id\", operator: \"eq\", value: otherNearAccounts[0]!.id },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\tupdate: { isPrimary: true },\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\n\t\t\t\t\tawait ctx.context.adapter.delete({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tconst accountToDelete: Account | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"account\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"providerId\", operator: \"eq\", value: \"siwn\" },\n\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: `${accountId}:${network}` },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (accountToDelete) {\n\t\t\t\t\t\tawait ctx.context.internalAdapter.deleteAccount(accountToDelete.id);\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\taccountId,\n\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\tmessage: \"NEAR account successfully unlinked\"\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tlistNearAccounts: createAuthEndpoint(\n\t\t\t\t\"/near/list-accounts\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tconst nearAccounts: NearAccount[] = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", operator: \"eq\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json(buildListAccountsResponse(nearAccounts));\n\t\t\t\t},\n\t\t\t),\n\t\t\tsetPrimaryNearAccount: createAuthEndpoint(\n\t\t\t\t\"/near/set-primary-account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: SetPrimaryAccountRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { accountId, network: providedNetwork } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tconst network = providedNetwork || getNetworkFromAccountId(accountId);\n\n\t\t\t\t\tconst targetAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!targetAccount) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"NEAR account not found or not linked to your user\",\n\t\t\t\t\t\t\tstatus: 404,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nearAccounts: NearAccount[] = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", operator: \"eq\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\tawait Promise.all(nearAccounts.map((account) => ctx.context.adapter.update({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [{ field: \"id\", operator: \"eq\", value: account.id }],\n\t\t\t\t\t\tupdate: { isPrimary: nearAccountKey(account) === nearAccountKey(targetAccount) },\n\t\t\t\t\t})));\n\n\t\t\t\t\tconst updatedNearAccounts: NearAccount[] = await ctx.context.adapter.findMany({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [{ field: \"userId\", operator: \"eq\", value: session.user.id }],\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\taccountId,\n\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\tmessage: \"Primary NEAR account updated\",\n\t\t\t\t\t\t...buildListAccountsResponse(updatedNearAccounts),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetSiwnNonce: createAuthEndpoint(\n\t\t\t\t\"/near/nonce\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: NonceRequest,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { accountId, networkId } = ctx.body;\n\t\t\t\t\tconst network = getNetworkFromAccountId(accountId);\n\n\t\t\t\t\tif (networkId !== network) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Network ID mismatch with account ID\",\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\tconst exists = await near.accountExists(accountId);\n\t\t\t\t\tif (!exists) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Account does not exist on-chain\",\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nonce = options.getNonce ? await options.getNonce() : generateNonce();\n\n\t\t\t\t\tconst nonceString = hex.encode(nonce);\n\n\t\t\t\t\tawait ctx.context.internalAdapter.createVerificationValue({\n\t\t\t\t\t\tidentifier: `siwn:${accountId}:${network}`,\n\t\t\t\t\t\tvalue: nonceString,\n\t\t\t\t\t\texpiresAt: new Date(Date.now() + 15 * 60 * 1000),\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json(NonceResponse.parse({ nonce: nonceString }));\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetSiwnProfile: createAuthEndpoint(\n\t\t\t\t\"/near/profile\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: ProfileRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { accountId } = ctx.body;\n\t\t\t\t\tlet targetAccountId = accountId;\n\n\t\t\t\t\tif (!targetAccountId) {\n\t\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\t\tif (!session) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Session required when no accountId provided\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!nearAccount) {\n\t\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\t\tmessage: \"No NEAR account found for user\",\n\t\t\t\t\t\t\t\tstatus: 404,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\ttargetAccountId = nearAccount.accountId;\n\t\t\t\t\t}\n\n\t\t\t\t\tconst profile = await (options.getProfile || ((id: AccountId) => defaultGetProfile(id, apiKey)))(targetAccountId);\n\t\t\t\t\treturn ctx.json(ProfileResponse.parse(profile));\n\t\t\t\t},\n\t\t\t),\n\t\t\tverifySiwnMessage: createAuthEndpoint(\n\t\t\t\t\"/near/verify\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: VerifyRequest,\n\t\t\t\t\trequireRequest: true,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst {\n\t\t\t\t\t\tsignedMessage,\n\t\t\t\t\t\tmessage,\n\t\t\t\t\t\trecipient,\n\t\t\t\t\t\tnonce,\n\t\t\t\t\t\taccountId,\n\t\t\t\t\t} = ctx.body;\n\t\t\t\t\tconst network = getNetworkFromAccountId(accountId);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\t\tconst nonceBytes = hex.decode(nonce);\n\n\t\t\t\t\t\tconst isValid = await verifyNep413Signature(\n\t\t\t\t\t\tsignedMessage,\n\t\t\t\t\t\t{ message, recipient, nonce: nonceBytes },\n\t\t\t\t\t\t\t{ near, maxAge: 15 * 60 * 1000 },\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!isValid) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Invalid signature\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (signedMessage.accountId !== accountId) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Account ID mismatch\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst publicKey = signedMessage.publicKey;\n\n\t\t\t\t\t\tconst nonceHash = await hashNonce(nonceBytes);\n\n\t\t\t\t\t\tconst existingNonce = await ctx.context.internalAdapter.findVerificationValue(\n\t\t\t\t\t\t\t`siwn-nonce:${nonceHash}`\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (existingNonce) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Nonce already used (replay attack detected)\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t\tcode: \"UNAUTHORIZED_NONCE_REPLAY\",\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait ctx.context.internalAdapter.createVerificationValue({\n\t\t\t\t\t\t\tidentifier: `siwn-nonce:${nonceHash}`,\n\t\t\t\t\t\t\tvalue: \"used\",\n\t\t\t\t\t\t\texpiresAt: new Date(Date.now() + 15 * 60 * 1000),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (!options.requireFullAccessKey) {\n\t\t\t\t\t\t\tconst validateKey = options.validateLimitedAccessKey\n\t\t\t\t\t\t\t\t|| ((args: { accountId: string; publicKey: string; recipient?: string }) =>\n\t\t\t\t\t\t\t\t\tdefaultValidateLimitedAccessKey(args.accountId, args.publicKey, args.recipient || getRecipient(network), near));\n\n\t\t\t\t\t\t\tconst isValidKey = await validateKey({\n\t\t\t\t\t\t\t\taccountId: accountId,\n\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\trecipient: options.recipient\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (!isValidKey) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\t\tmessage: \"Unauthorized: Invalid function call access key\",\n\t\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tlet user: User | null = null;\n\n\t\t\t\t\t\tconst existingNearAccount: NearAccount | null =\n\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t\t\t{ field: \"network\", operator: \"eq\", value: network },\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\tif (existingNearAccount) {\n\t\t\t\t\t\t\tuser = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\tmodel: \"user\",\n\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\t\t\t\t\toperator: \"eq\",\n\t\t\t\t\t\t\t\t\t\tvalue: existingNearAccount.userId,\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tconst anyNearAccount: NearAccount | null =\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t{ field: \"accountId\", operator: \"eq\", value: accountId },\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tif (anyNearAccount) {\n\t\t\t\t\t\t\t\tuser = await ctx.context.adapter.findOne({\n\t\t\t\t\t\t\t\t\tmodel: \"user\",\n\t\t\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t\t\t{\n\t\t\t\t\t\t\t\t\t\t\tfield: \"id\",\n\t\t\t\t\t\t\t\t\t\t\toperator: \"eq\",\n\t\t\t\t\t\t\t\t\t\t\tvalue: anyNearAccount.userId,\n\t\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (!user) {\n\t\t\t\t\t\t\tconst userEmail = deriveEmail(accountId, getRecipient(network));\n\n\t\t\t\t\t\t\tconst profile = await (options.getProfile || ((id: AccountId) => defaultGetProfile(id, apiKey)))(accountId);\n\n\t\t\t\t\t\t\tuser = await ctx.context.internalAdapter.createUser({\n\t\t\t\t\t\t\t\tname: profile?.name ?? accountId,\n\t\t\t\t\t\t\t\temail: userEmail,\n\t\t\t\t\t\t\t\timage: profile?.image ? getImageUrl(profile.image) : \"\",\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\t\tisPrimary: true,\n\t\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\tawait ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\t\tproviderId: \"siwn\",\n\t\t\t\t\t\t\t\taccountId: `${accountId}:${network}`,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\tif (!existingNearAccount) {\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\t\t\tpublicKey: publicKey,\n\t\t\t\t\t\t\t\t\t\tisPrimary: false,\n\t\t\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t\t\t\t});\n\n\t\t\t\t\t\t\t\tawait ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\t\t\t\tuserId: user.id,\n\t\t\t\t\t\t\t\t\tproviderId: \"siwn\",\n\t\t\t\t\t\t\t\t\taccountId: `${accountId}:${network}`,\n\t\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait ensureRelayer(ctx.context.adapter, ctx.context.secret, network);\n\n\t\t\t\t\t\tconst session = await ctx.context.internalAdapter.createSession(\n\t\t\t\t\t\t\tuser.id\n\t\t\t\t\t\t);\n\n\t\t\t\t\t\tif (!session) {\n\t\t\t\t\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\t\t\t\t\tmessage: \"Internal Server Error\",\n\t\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tawait setSessionCookie(ctx, { session, user });\n\n\t\t\t\t\t\treturn ctx.json(VerifyResponse.parse({\n\t\t\t\t\t\t\ttoken: session.token,\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\tuser: {\n\t\t\t\t\t\t\t\tid: user.id,\n\t\t\t\t\t\t\t\taccountId,\n\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t}));\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (error instanceof APIError) throw error;\n\t\t\t\t\t\tconst msg = error instanceof Error ? error.message : \"Unknown error\";\n\t\t\t\t\t\tconst at = error instanceof Error && error.stack ? error.stack.split(\"\\n\").slice(1, 3).map(s => s.trim()).join(\" <- \") : \"\";\n\t\t\t\t\t\tconsole.error(`[siwn] Verify error: ${msg}${at ? ` (${at})` : \"\"}`);\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Something went wrong. Please try again later.\",\n\t\t\t\t\t\t\terror: msg,\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\trelayNearTransaction: createAuthEndpoint(\n\t\t\t\t\"/near/relay\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: RelayRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { payload } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Must be authenticated to relay transactions\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!nearAccount) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"No NEAR account linked to session\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst network = nearAccount.network as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst rState = await ensureRelayer(ctx.context.adapter, ctx.context.secret, network);\n\n\t\t\t\t\tif (!rState) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Relayer not configured\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst decoded: SignedDelegateAction = decodeSignedDelegateAction(payload);\n\t\t\t\t\t\tconst delegateAction = decoded.signedDelegate.delegateAction;\n\n\t\t\t\t\t\tif (delegateAction.senderId !== nearAccount.accountId) {\n\t\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\t\tmessage: \"Delegate action sender does not match session account\",\n\t\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t\t});\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst relayerConfigForNetwork = getRelayerConfig(network);\n\t\t\t\t\t\tif (relayerConfigForNetwork?.whitelistedContracts?.length) {\n\t\t\t\t\t\t\tif (!relayerConfigForNetwork.whitelistedContracts.includes(delegateAction.receiverId)) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"FORBIDDEN\", {\n\t\t\t\t\t\t\t\t\tmessage: `Contract ${delegateAction.receiverId} is not whitelisted for relay`,\n\t\t\t\t\t\t\t\t\tstatus: 403,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (relayerConfigForNetwork?.maxGasPerTransaction) {\n\t\t\t\t\t\t\tconst totalGas = delegateAction.actions.reduce((sum: bigint, a) => {\n\t\t\t\t\t\t\t\treturn sum + (\"functionCall\" in a ? a.functionCall.gas : 0n);\n\t\t\t\t\t\t\t}, 0n);\n\t\t\t\t\t\t\tif (totalGas > BigInt(relayerConfigForNetwork.maxGasPerTransaction)) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: `Transaction gas (${totalGas}) exceeds relayer limit (${relayerConfigForNetwork.maxGasPerTransaction})`,\n\t\t\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tif (relayerConfigForNetwork?.maxDepositPerTransaction) {\n\t\t\t\t\t\t\tconst totalDeposit = delegateAction.actions.reduce((sum: bigint, a) => {\n\t\t\t\t\t\t\t\tif (\"functionCall\" in a) return sum + a.functionCall.deposit;\n\t\t\t\t\t\t\t\tif (\"transfer\" in a) return sum + a.transfer.deposit;\n\t\t\t\t\t\t\t\treturn sum;\n\t\t\t\t\t\t\t}, 0n);\n\t\t\t\t\t\t\tif (totalDeposit > BigInt(relayerConfigForNetwork.maxDepositPerTransaction)) {\n\t\t\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\t\t\tmessage: `Transaction deposit (${totalDeposit}) exceeds relayer limit (${relayerConfigForNetwork.maxDepositPerTransaction})`,\n\t\t\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tconst result = await relayOnChain(payload, rState);\n\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"relayedTransaction\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\ttxHash: result.txHash,\n\t\t\t\t\t\t\t\tsenderId: delegateAction.senderId,\n\t\t\t\t\t\t\t\treceiverId: delegateAction.receiverId,\n\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\tif (rState.mode === \"ephemeral\") {\n\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\tmodel: \"relayerKey\",\n\t\t\t\t\t\t\twhere: [{ field: \"network\", operator: \"eq\", value: network }],\n\t\t\t\t\t\t\tupdate: { lastUsedAt: new Date() },\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\t\treturn ctx.json(RelayResponse.parse({\n\t\t\t\t\t\t\ttxHash: result.txHash,\n\t\t\t\t\t\t\tstatus: \"pending\",\n\t\t\t\t\t\t}));\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (error instanceof APIError) throw error;\n\t\t\t\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\t\t\t\tmessage: error instanceof Error ? error.message : \"Relay failed\",\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetRelayStatus: createAuthEndpoint(\n\t\t\t\t\"/near/relay-status/:txHash\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst txHash = (ctx.params as Record<string, string>)?.txHash;\n\t\t\t\t\tif (!txHash) {\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: \"Transaction hash required\",\n\t\t\t\t\t\t\tstatus: 400,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tconst relayedTx = await ctx.context.adapter.findOne<RelayedTransactionRecord>({\n\t\t\t\t\t\tmodel: \"relayedTransaction\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"txHash\", operator: \"eq\", value: txHash },\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tif (!relayedTx) {\n\t\t\t\t\t\tthrow new APIError(\"NOT_FOUND\", {\n\t\t\t\t\t\t\tmessage: \"Transaction not found or not owned by this user\",\n\t\t\t\t\t\t\tstatus: 404,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst network = relayedTx.network;\n\t\t\t\t\tconst senderId = relayedTx.senderId;\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\t\tconst txResult = await near.getTransactionStatus(txHash, senderId);\n\n\t\t\t\t\t\tconst txStatus = txResult.status;\n\t\t\t\t\t\tif (txStatus && typeof txStatus === \"object\") {\n\t\t\t\t\t\t\tconst hasSuccess = \"SuccessValue\" in txStatus || \"SuccessReceiptId\" in txStatus;\n\t\t\t\t\t\t\tconst hasFailure = \"Failure\" in txStatus;\n\t\t\t\t\t\t\tconst status = hasSuccess ? \"completed\" : hasFailure ? \"failed\" : \"pending\";\n\n\t\t\t\t\t\t\tif (status !== \"pending\") {\n\t\t\t\t\t\t\t\tawait ctx.context.adapter.update({\n\t\t\t\t\t\t\t\t\tmodel: \"relayedTransaction\",\n\t\t\t\t\t\t\t\t\twhere: [{ field: \"txHash\", operator: \"eq\", value: txHash }],\n\t\t\t\t\t\t\t\t\tupdate: { status },\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tconst gasUsed = txResult.transaction_outcome?.outcome?.gas_burnt?.toString();\n\n\t\t\t\t\t\t\treturn ctx.json(RelayStatusResponse.parse({\n\t\t\t\t\t\t\t\tstatus,\n\t\t\t\t\t\t\t\tgasUsed,\n\t\t\t\t\t\t\t\toutcome: txResult,\n\t\t\t\t\t\t\t}));\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\treturn ctx.json(RelayStatusResponse.parse({ status: \"pending\" }));\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\treturn ctx.json(RelayStatusResponse.parse({ status: \"pending\" }));\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetRelayerInfo: createAuthEndpoint(\n\t\t\t\t\"/near/relayer-info\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: GetRelayerInfoRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { network: requestedNetwork } = ctx.body;\n\t\t\t\t\tconst targetNetwork = (requestedNetwork ?? primaryNetwork) as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst rState = await ensureRelayer(ctx.context.adapter, ctx.context.secret, targetNetwork);\n\n\t\t\t\t\tif (!rState) {\n\t\t\t\t\t\treturn ctx.json({ enabled: false, subAccountAvailable: false } satisfies Partial<RelayerInfo> & { enabled: boolean });\n\t\t\t\t\t}\n\n\t\t\t\t\tconst subAccountCfg = getSubAccountConfig(targetNetwork);\n\t\t\t\t\tconst { parentAccount, subAccountAvailable } = resolveParentAccount(subAccountCfg, rState);\n\n\t\t\t\t\tconst near = getNear(rState.network);\n\t\t\t\t\tlet account;\n\t\t\t\t\ttry {\n\t\t\t\t\t\taccount = await near.getAccount(rState.accountId);\n\t\t\t\t\t} catch {\n\t\t\t\t\t\taccount = {\n\t\t\t\t\t\t\tbalance: \"0\",\n\t\t\t\t\t\t\tavailable: \"0\",\n\t\t\t\t\t\t\tstaked: \"0\",\n\t\t\t\t\t\t\tstorageUsage: \"0\",\n\t\t\t\t\t\t\tstorageBytes: 0,\n\t\t\t\t\t\t\thasContract: false,\n\t\t\t\t\t\t\tcodeHash: \"\",\n\t\t\t\t\t\t};\n\t\t\t\t\t}\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\tenabled: true,\n\t\t\t\t\t\taccountId: rState.accountId,\n\t\t\t\t\t\tmode: rState.mode,\n\t\t\t\t\t\tnetwork: rState.network,\n\t\t\t\t\t\tpublicKey: rState.publicKey,\n\t\t\t\t\t\tbalance: account.balance,\n\t\t\t\t\t\tavailable: account.available,\n\t\t\t\t\t\tstaked: account.staked,\n\t\t\t\t\t\tstorageUsage: account.storageUsage,\n\t\t\t\t\t\tstorageBytes: account.storageBytes,\n\t\t\t\t\t\thasContract: account.hasContract,\n\t\t\t\t\t\thasKey: true,\n\t\t\t\t\t\tcreatedAt: rState.createdAt,\n\t\t\t\t\t\tlastUsedAt: rState.lastUsedAt,\n\t\t\t\t\t\tparentAccount: parentAccount ?? undefined,\n\t\t\t\t\t\tsubAccountAvailable,\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tgetRelayHistory: createAuthEndpoint(\n\t\t\t\t\"/near/relay-history\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"GET\",\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tlet transactions: RelayedTransactionRecord[] = [];\n\t\t\t\t\ttry {\n\t\t\t\t\t\tconst result = await ctx.context.adapter.findMany<RelayedTransactionRecord>({\n\t\t\t\t\t\t\tmodel: \"relayedTransaction\",\n\t\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t});\n\t\t\t\t\t\ttransactions = result || [];\n\t\t\t\t\t} catch (err) {\n\t\t\t\t\t\tconsole.error(\"relay-history findMany error:\", err);\n\t\t\t\t\t}\n\n\t\t\t\t\tconst sorted = transactions.sort((a, b) => {\n\t\t\t\t\t\tconst aTime = a.createdAt instanceof Date ? a.createdAt.getTime() : new Date(a.createdAt ?? 0).getTime();\n\t\t\t\t\t\tconst bTime = b.createdAt instanceof Date ? b.createdAt.getTime() : new Date(b.createdAt ?? 0).getTime();\n\t\t\t\t\t\treturn bTime - aTime;\n\t\t\t\t\t});\n\n\t\t\t\t\treturn ctx.json({\n\t\t\t\t\t\ttransactions: sorted.map((tx) => ({\n\t\t\t\t\t\t\tid: String(tx.id ?? \"\"),\n\t\t\t\t\t\t\tuserId: String(tx.userId ?? \"\"),\n\t\t\t\t\t\t\ttxHash: String(tx.txHash ?? \"\"),\n\t\t\t\t\t\t\tsenderId: String(tx.senderId ?? \"\"),\n\t\t\t\t\t\t\treceiverId: String(tx.receiverId ?? \"\"),\n\t\t\t\t\t\t\tnetwork: String(tx.network ?? \"mainnet\"),\n\t\t\t\t\t\t\tstatus: String(tx.status ?? \"pending\"),\n\t\t\t\t\t\t\tgasUsed: tx.gasUsed ? String(tx.gasUsed) : undefined,\n\t\t\t\t\t\t\tcreatedAt: tx.createdAt instanceof Date ? tx.createdAt.toISOString() : tx.createdAt ? String(tx.createdAt) : new Date().toISOString(),\n\t\t\t\t\t\t\tupdatedAt: tx.updatedAt instanceof Date ? tx.updatedAt.toISOString() : tx.updatedAt ? String(tx.updatedAt) : undefined,\n\t\t\t\t\t\t})),\n\t\t\t\t\t});\n\t\t\t\t},\n\t\t\t),\n\t\t\tviewContract: createAuthEndpoint(\n\t\t\t\t\"/near/view\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: ViewContractRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { contractId, methodName, args } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tconst network = (nearAccount?.network || primaryNetwork) as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\tlet result: unknown;\n\t\t\t\t\ttry {\n\t\t\t\t\t\tresult = await near.view(contractId, methodName, args ?? {});\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tif (error instanceof APIError) throw error;\n\t\t\t\t\t\tthrow new APIError(\"BAD_REQUEST\", {\n\t\t\t\t\t\t\tmessage: error instanceof Error ? error.message : \"Unknown error\",\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t\treturn ctx.json(ViewContractResponse.parse({ result }));\n\t\t\t\t},\n\t\t\t),\n\t\t\tcreateSubAccount: createAuthEndpoint(\n\t\t\t\t\"/near/create-sub-account\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: CreateSubAccountRequest,\n\t\t\t\t\tuse: [sessionMiddleware],\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { subAccountName, network: providedNetwork, publicKey } = ctx.body;\n\t\t\t\t\tconst session = ctx.context.session;\n\n\t\t\t\t\tif (!session) {\n\t\t\t\t\t\tthrow new APIError(\"UNAUTHORIZED\", {\n\t\t\t\t\t\t\tmessage: \"Must be authenticated to create a sub-account\",\n\t\t\t\t\t\t\tstatus: 401,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst nearAccount: NearAccount | null = await ctx.context.adapter.findOne({\n\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\twhere: [\n\t\t\t\t\t\t\t{ field: \"userId\", operator: \"eq\", value: session.user.id },\n\t\t\t\t\t\t\t{ field: \"isPrimary\", operator: \"eq\", value: true },\n\t\t\t\t\t\t],\n\t\t\t\t\t});\n\n\t\t\t\t\tconst network = (providedNetwork || nearAccount?.network || primaryNetwork) as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst subAccountCfg = getSubAccountConfig(network);\n\t\t\t\t\tconst rState = await ensureRelayer(ctx.context.adapter, ctx.context.secret, network);\n\n\t\t\t\t\tif (!rState) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Relayer not configured — sub-account creation requires a funded relayer\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst { parentAccount, subAccountAvailable } = resolveParentAccount(subAccountCfg, rState);\n\n\t\t\t\t\tif (!subAccountAvailable || !parentAccount) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Sub-account creation requires a named parent account. Configure subAccount.parentAccount in your SIWN plugin options, or use an explicit relayer with a named account.\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tif (parentAccount !== rState.accountId && !subAccountCfg?.parentKey) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Sub-account parent differs from relayer account. Configure subAccount.parentKey to enable signing as the parent account.\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst newAccountId = `${subAccountName}.${parentAccount}`;\n\t\t\t\t\tconst minDeposit = subAccountCfg?.minDeposit || \"0.1 NEAR\";\n\n\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\tconst exists = await near.accountExists(newAccountId);\n\t\t\t\t\tif (exists) {\n\t\t\t\t\t\tthrow new APIError(\"CONFLICT\", {\n\t\t\t\t\t\t\tmessage: `Account ${newAccountId} already exists on ${network}`,\n\t\t\t\t\t\t\tstatus: 409,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tlet txBuilder = rState.near\n\t\t\t\t\t\t.transaction(parentAccount)\n\t\t\t\t\t\t.createAccount(newAccountId)\n\t\t\t\t\t\t.addKey(publicKey, { type: \"fullAccess\" });\n\n\t\t\t\t\tif (subAccountCfg?.parentKey) {\n\t\t\t\t\t\ttxBuilder = txBuilder.signWith(subAccountCfg.parentKey as PrivateKey);\n\t\t\t\t\t}\n\n\t\t\t\t\tif (subAccountCfg?.addRelayerFCAK !== false && subAccountCfg?.relayerFCAK) {\n\t\t\t\t\t\tconst fcakPermission: { type: \"functionCall\"; receiverId: string; methodNames?: string[]; allowance?: string } = {\n\t\t\t\t\t\t\ttype: \"functionCall\",\n\t\t\t\t\t\t\treceiverId: subAccountCfg.relayerFCAK.receiverId,\n\t\t\t\t\t\t};\n\t\t\t\t\t\tif (subAccountCfg.relayerFCAK.methodNames) {\n\t\t\t\t\t\t\tfcakPermission.methodNames = subAccountCfg.relayerFCAK.methodNames;\n\t\t\t\t\t\t}\n\t\t\t\t\t\tif (subAccountCfg.relayerFCAK.allowance) {\n\t\t\t\t\t\t\tfcakPermission.allowance = subAccountCfg.relayerFCAK.allowance as `${number} NEAR` | `${bigint} yocto`;\n\t\t\t\t\t\t}\n\t\t\t\t\t\ttxBuilder.addKey(rState.publicKey, fcakPermission as any);\n\t\t\t\t\t}\n\n\t\t\t\t\ttxBuilder.transfer(newAccountId, minDeposit as `${number} NEAR`);\n\n\t\t\t\t\ttry {\n\t\t\t\t\t\tawait txBuilder.send({ waitUntil: \"EXECUTED\" });\n\n\t\t\t\t\t\tawait ctx.context.adapter.create({\n\t\t\t\t\t\t\tmodel: \"nearAccount\",\n\t\t\t\t\t\t\tdata: {\n\t\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\t\taccountId: newAccountId,\n\t\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\t\tpublicKey,\n\t\t\t\t\t\t\t\tisPrimary: false,\n\t\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\t},\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\tawait ctx.context.internalAdapter.createAccount({\n\t\t\t\t\t\t\tuserId: session.user.id,\n\t\t\t\t\t\t\tproviderId: \"siwn\",\n\t\t\t\t\t\t\taccountId: `${newAccountId}:${network}`,\n\t\t\t\t\t\t\tcreatedAt: new Date(),\n\t\t\t\t\t\t\tupdatedAt: new Date(),\n\t\t\t\t\t\t});\n\n\t\t\t\t\t\treturn ctx.json(CreateSubAccountResponse.parse({\n\t\t\t\t\t\t\tsuccess: true,\n\t\t\t\t\t\t\taccountId: newAccountId,\n\t\t\t\t\t\t\tnetwork,\n\t\t\t\t\t\t\tpublicKey,\n\t\t\t\t\t\t\tmessage: `Sub-account ${newAccountId} created on ${network}`,\n\t\t\t\t\t\t}));\n\t\t\t\t\t} catch (error: unknown) {\n\t\t\t\t\t\tconst msg = error instanceof Error ? error.message : \"Unknown error\";\n\t\t\t\t\t\tthrow new APIError(\"INTERNAL_SERVER_ERROR\", {\n\t\t\t\t\t\t\tmessage: `Failed to create sub-account: ${msg}`,\n\t\t\t\t\t\t\tstatus: 500,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t),\n\t\t\tcheckSubAccountAvailability: createAuthEndpoint(\n\t\t\t\t\"/near/check-sub-account-availability\",\n\t\t\t\t{\n\t\t\t\t\tmethod: \"POST\",\n\t\t\t\t\tbody: CheckSubAccountAvailabilityRequest,\n\t\t\t\t},\n\t\t\t\tasync (ctx) => {\n\t\t\t\t\tconst { subAccountName, network: providedNetwork } = ctx.body;\n\n\t\t\t\t\tconst network = (providedNetwork || primaryNetwork) as \"mainnet\" | \"testnet\";\n\t\t\t\t\tconst subAccountCfg = getSubAccountConfig(network);\n\t\t\t\t\tconst rState = await ensureRelayer(ctx.context.adapter, ctx.context.secret, network);\n\n\t\t\t\t\tconst { parentAccount, subAccountAvailable } = resolveParentAccount(subAccountCfg, rState);\n\n\t\t\t\t\tif (!subAccountAvailable || !parentAccount) {\n\t\t\t\t\t\tthrow new APIError(\"SERVICE_UNAVAILABLE\", {\n\t\t\t\t\t\t\tmessage: \"Sub-account creation requires a named parent account. Configure subAccount.parentAccount in your SIWN plugin options, or use an explicit relayer with a named account.\",\n\t\t\t\t\t\t\tstatus: 503,\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\n\t\t\t\t\tconst accountId = `${subAccountName}.${parentAccount}`;\n\n\t\t\t\t\tconst near = getNear(network);\n\t\t\t\t\tconst exists = await near.accountExists(accountId);\n\n\t\t\t\t\treturn ctx.json(CheckSubAccountAvailabilityResponse.parse({\n\t\t\t\t\t\tavailable: !exists,\n\t\t\t\t\t\taccountId,\n\t\t\t\t\t}));\n\t\t\t\t},\n\t\t\t),\n\t\t},\n\t});\n};\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "better-near-auth",
3
- "version": "1.6.3",
3
+ "version": "1.6.4",
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.6.3"
11
+ library_version: "1.6.4"
12
12
  sources:
13
13
  - "elliotBraem/better-near-auth:src/client.ts"
14
14
  - "elliotBraem/better-near-auth:src/types.ts"
@@ -204,11 +204,18 @@ const result = await authClient.near.view({
204
204
  | `link(callbacks?)` | `Promise<void>` | Link NEAR account to session |
205
205
  | `unlink(params)` | `Promise<Response>` | Unlink NEAR account |
206
206
  | `listAccounts()` | `Promise<Response>` | List linked NEAR accounts |
207
+ | `setPrimaryAccount(params)` | `Promise<Response<SetPrimaryAccountResponse>>` | Set primary linked NEAR account |
208
+ | `createSubAccount(params)` | `Promise<Response<CreateSubAccountResponse>>` | Create a sub-account |
209
+ | `checkSubAccountAvailability(params)` | `Promise<Response<CheckSubAccountAvailabilityResponse>>` | Check if a sub-account name is available |
207
210
  | `buildSignedDelegateAction(receiverId, buildActions)` | `Promise<string>` | Build + sign delegate action, returns base64 payload |
208
211
  | `relayTransaction({ payload })` | `Promise<Response<RelayResponse>>` | Submit delegate action to relayer |
209
212
  | `getRelayStatus(txHash)` | `Promise<Response<RelayStatusResponse>>` | Check relayed tx status |
210
213
  | `getRelayerInfo()` | `Promise<Response<RelayerInfo>>` | Get relayer info and balance |
211
214
  | `relayHistory()` | `Promise<Response<RelayHistoryResponse>>` | List relayed transactions |
215
+ | `setNetwork(network)` | `void` | Switch active network (mainnet/testnet) |
216
+ | `getNetwork()` | `"mainnet" \| "testnet"` | Get currently active network |
217
+ | `getSupportedNetworks()` | `("mainnet" \| "testnet")[]` | List supported networks |
218
+ | `getRecipient(network?)` | `string` | Get configured recipient for a network |
212
219
  | `client` | `Near` | Access near-kit Near instance (throws on server) |
213
220
 
214
221
  ### authClient.signIn
@@ -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.6.3"
11
+ library_version: "1.6.4"
12
12
  sources:
13
13
  - "elliotBraem/better-near-auth:src/index.ts"
14
14
  - "elliotBraem/better-near-auth:src/utils.ts"
@@ -139,7 +139,7 @@ View calls are read-only, authenticated, and executed server-side.
139
139
  | ------ | ---- | ----------- |
140
140
  | POST | `/near/relay` | Relay a signed delegate action on-chain |
141
141
  | GET | `/near/relay-status/:txHash` | Check relayed transaction status |
142
- | GET | `/near/relayer-info` | Get relayer accountId, mode, balance |
142
+ | POST | `/near/relayer-info` | Get relayer accountId, mode, balance |
143
143
  | GET | `/near/relay-history` | List relayed transactions for current user |
144
144
  | POST | `/near/view` | Server-side read-only contract call |
145
145
 
@@ -284,12 +284,4 @@ The ephemeral relayer encrypts its private key using HKDF-SHA256 derived from `B
284
284
 
285
285
  Source: src/utils.ts:21-41, src/index.ts:134
286
286
 
287
- ### HIGH Tension: Ephemeral simplicity vs production reliability
288
287
 
289
- Ephemeral mode is zero-config but requires funding an implicit account with no human-readable name. Explicit mode uses a named, pre-funded account but requires managing private keys securely. Agents optimizing for setup simplicity may default to ephemeral without warning about the funding requirement, or use explicit mode with the private key hardcoded instead of using environment variables.
290
-
291
- See also: client/SKILL.md — delegate action building pattern
292
-
293
- ### HIGH Tension: Whitelist security vs development flexibility
294
-
295
- Strict `whitelistedContracts` prevents relay abuse but blocks calls to new contracts during development. Omitting the whitelist enables any contract call at the relayer's expense. Agents may copy quickstart examples without `whitelistedContracts` into production code, or add overly permissive whitelists that defeat the security purpose.
@@ -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.6.3"
11
+ library_version: "1.6.4"
12
12
  sources:
13
13
  - "elliotBraem/better-near-auth:src/index.ts"
14
14
  - "elliotBraem/better-near-auth:src/profile.ts"
@@ -122,6 +122,7 @@ You cannot unlink the last authentication method — link another account first.
122
122
  | POST | `/near/link-account` | Link NEAR account to session |
123
123
  | POST | `/near/unlink-account` | Unlink NEAR account |
124
124
  | GET | `/near/list-accounts` | List linked NEAR accounts |
125
+ | POST | `/near/set-primary-account` | Set primary linked NEAR account |
125
126
 
126
127
  ## Plugin Options
127
128
 
@@ -135,6 +136,8 @@ You cannot unlink the last authentication method — link another account first.
135
136
  | `apiKey` | `string` | `process.env.FASTNEAR_API_KEY` | API key for RPC |
136
137
  | `rpcUrl` | `string` | — | Custom RPC URL |
137
138
  | `relayer` | `RelayerConfig` | — | See relay skill |
139
+ | `recipients` | `DualNetworkConfig<string>` | — | Per-network recipient (overrides `recipient` for mainnet/testnet) |
140
+ | `subAccount` | `SubAccountConfig \| DualNetworkConfig<SubAccountConfig>` | — | Sub-account configuration for delegated account creation |
138
141
 
139
142
  ## Email Handling
140
143
 
@@ -12,7 +12,7 @@ requires:
12
12
  - client
13
13
  - siwn
14
14
  library: better-near-auth
15
- library_version: "1.6.3"
15
+ library_version: "1.6.4"
16
16
  sources:
17
17
  - "elliotBraem/better-near-auth:src/client.ts"
18
18
  - "elliotBraem/better-near-auth:examples/auth.everything.dev/ui/src/lib/auth.ts"
@@ -235,6 +235,8 @@ Methods that throw on server: `buildSignedDelegateAction`, `ensureConnected`, `s
235
235
 
236
236
  Properties that return defaults on server: `getAccountId()` → `null`, `getState()` → `null`, `isWalletConnected()` → `false`.
237
237
 
238
+ See also: siwn/SKILL.md — server-side plugin options such as `recipient`, `requireFullAccessKey`, and custom profile/access key validation
239
+
238
240
  ## File Consolidation
239
241
 
240
242
  Replace three separate files with one `auth.ts`: