UNPKG

@fastnear/wallet-adapter

Version:

Wallet adapter implementations for Meteor Wallet and Near Mobile

1 lines 32.3 kB
{"version":3,"sources":["../../src/near-mobile.ts"],"sourcesContent":["import { serialize as borshSerialize, type Schema } from \"@fastnear/borsh\";\nimport { ed25519 } from \"@noble/curves/ed25519.js\";\nimport { secp256k1 } from \"@noble/curves/secp256k1.js\";\nimport {\n base64ToBytes,\n curveFromKey,\n keyFromString,\n privateKeyFromRandom,\n publicKeyFromPrivate,\n sha256,\n} from \"@fastnear/utils\";\nimport { createRpcFactory } from \"./rpc.js\";\nimport { TransportError, UserRejectedError } from \"./errors.js\";\nimport { createDefaultStorage, readJson, writeJson } from \"./storage.js\";\nimport { defaultPollingOptions, visibilityAwarePoll } from \"./polling.js\";\nimport type {\n AdapterStorage,\n ConnectorActionLike,\n NearMobileAdapterOptions,\n NearMobileMetadata,\n SignAndSendTransactionParams,\n SignAndSendTransactionsParams,\n SignInParams,\n SignMessageParams,\n WalletAccount,\n WalletNetwork,\n} from \"./types.js\";\n\nconst DEFAULT_SIGNER_BACKEND_URL = \"https://near-mobile-signer-backend_production.peersyst.tech\";\nconst DEFAULT_NEAR_MOBILE_WALLET_URL = \"near-mobile-wallet://sign\";\nconst SESSION_KEY = \"session\";\nconst NEP413_TAG = 2147484061;\n\ntype SignerRequestStatus = \"pending\" | \"approved\" | \"rejected\";\n\ninterface SessionState {\n mainnet: {\n activeAccount: string | null;\n accounts: Record<string, string>;\n };\n testnet: {\n activeAccount: string | null;\n accounts: Record<string, string>;\n };\n}\n\ninterface SignerRequestStatusDto {\n id: string;\n status: SignerRequestStatus;\n}\n\ninterface SignerRequestDto {\n id: string;\n status: SignerRequestStatus;\n network: WalletNetwork;\n signerAccountId?: string;\n requests?: any[];\n txHash?: string[];\n}\n\ninterface SignMessageResponseDto {\n accountId: string;\n publicKey: string;\n signature: string;\n}\n\ninterface SignMessageRequestDto {\n id: string;\n network: WalletNetwork;\n status: SignerRequestStatus;\n response?: SignMessageResponseDto;\n}\n\nconst ensureNetwork = (network: string): WalletNetwork => {\n if (network !== \"mainnet\" && network !== \"testnet\") {\n throw new TransportError(\"INVALID_NETWORK\", `Unsupported network: ${network}`);\n }\n return network;\n};\n\nconst normalizeError = (error: unknown, fallbackCode: string, fallbackMessage: string): Error => {\n if (error instanceof TransportError || error instanceof UserRejectedError) return error;\n if (error instanceof Error) return new TransportError(fallbackCode, error.message, { cause: error });\n return new TransportError(fallbackCode, fallbackMessage, { details: error });\n};\n\nconst signMessagePayloadSchema: Schema = {\n struct: {\n tag: \"u32\",\n message: \"string\",\n nonce: { array: { type: \"u8\", len: 32 } },\n recipient: \"string\",\n callbackUrl: { option: \"string\" },\n },\n};\n\nconst verifyNep413Signature = ({\n publicKey,\n signature,\n message,\n nonce,\n recipient,\n callbackUrl,\n}: {\n publicKey: string;\n signature: string;\n message: string;\n nonce: number[];\n recipient: string;\n callbackUrl?: string;\n}): boolean => {\n const borshPayload = borshSerialize(signMessagePayloadSchema, {\n tag: NEP413_TAG,\n message,\n nonce: Uint8Array.from(nonce),\n recipient,\n callbackUrl: callbackUrl ?? null,\n });\n\n const hash = sha256(new Uint8Array(borshPayload));\n const pk = keyFromString(publicKey);\n const sig = base64ToBytes(signature);\n\n if (curveFromKey(publicKey) === \"secp256k1\") {\n // Strip recovery byte (last byte) — compact sig is first 64 bytes\n const compactSig = sig.slice(0, 64);\n // Prepend 0x04 uncompressed prefix — NEAR stores 64 bytes, noble expects 65\n const fullPk = new Uint8Array(65);\n fullPk[0] = 0x04;\n fullPk.set(pk, 1);\n return secp256k1.verify(compactSig, hash, fullPk, { prehash: false });\n }\n\n return ed25519.verify(sig, hash, pk);\n};\n\nclass SessionRepository {\n private readonly storage: AdapterStorage;\n private readonly key: string;\n\n constructor(storage: AdapterStorage, key = SESSION_KEY) {\n this.storage = storage;\n this.key = key;\n }\n\n private defaultState(): SessionState {\n return {\n mainnet: { activeAccount: null, accounts: {} },\n testnet: { activeAccount: null, accounts: {} },\n };\n }\n\n async get(): Promise<SessionState> {\n return readJson<SessionState>(this.storage, this.key, this.defaultState());\n }\n\n async set(state: SessionState): Promise<void> {\n await writeJson(this.storage, this.key, state);\n }\n\n async getKey(network: WalletNetwork, accountId: string): Promise<string> {\n const state = await this.get();\n const key = state[network]?.accounts[accountId];\n if (key == null) {\n throw new TransportError(\"ACCOUNT_KEY_NOT_FOUND\", \"Account key not found in session storage\");\n }\n return key;\n }\n\n async setKey(network: WalletNetwork, accountId: string, privateKey: string): Promise<void> {\n const state = await this.get();\n state[network].accounts[accountId] = privateKey;\n await this.set(state);\n }\n\n async removeKey(network: WalletNetwork, accountId: string): Promise<void> {\n const state = await this.get();\n if (state[network].activeAccount === accountId) {\n state[network].activeAccount = null;\n }\n delete state[network].accounts[accountId];\n await this.set(state);\n }\n\n async getActiveAccount(network: WalletNetwork): Promise<string | null> {\n const state = await this.get();\n return state[network].activeAccount ?? null;\n }\n\n async setActiveAccount(network: WalletNetwork, accountId: string): Promise<void> {\n const state = await this.get();\n const exists = Object.prototype.hasOwnProperty.call(state[network].accounts, accountId);\n if (!exists) {\n throw new TransportError(\"INVALID_ACCOUNT_ID\", \"Cannot set active account that does not exist in session storage\");\n }\n state[network].activeAccount = accountId;\n await this.set(state);\n }\n\n async getAccounts(network: WalletNetwork): Promise<string[]> {\n const state = await this.get();\n return Object.keys(state[network].accounts);\n }\n}\n\nclass NearMobileApiClient {\n private readonly backendUrl: string;\n private readonly fetcher: typeof fetch;\n\n constructor(backendUrl: string, fetcher?: typeof fetch) {\n this.backendUrl = backendUrl.replace(/\\/$/, \"\");\n this.fetcher = fetcher ?? fetch;\n }\n\n private async request<T>(path: string, init: RequestInit = {}, timeoutMs = 30_000): Promise<T> {\n const controller = new AbortController();\n const timeout = setTimeout(() => controller.abort(), timeoutMs);\n\n try {\n const response = await this.fetcher(`${this.backendUrl}${path}`, {\n ...init,\n headers: {\n \"Content-Type\": \"application/json\",\n ...(init.headers ?? {}),\n },\n signal: controller.signal,\n });\n\n if (!response.ok) {\n const text = await response.text().catch(() => \"Unknown API error\");\n throw new TransportError(\"API_HTTP_ERROR\", `Near Mobile backend request failed (${response.status}): ${text}`);\n }\n\n if (response.status === 204) {\n return undefined as T;\n }\n\n return (await response.json()) as T;\n } catch (error: any) {\n if (controller.signal.aborted) {\n throw new TransportError(\"API_TIMEOUT\", \"Near Mobile backend request timed out\", { cause: error });\n }\n if (error instanceof TransportError) throw error;\n throw new TransportError(\"API_NETWORK_ERROR\", \"Near Mobile backend request failed\", { cause: error });\n } finally {\n clearTimeout(timeout);\n }\n }\n\n async createRequest(network: WalletNetwork, transactions: any[], metadata?: NearMobileMetadata): Promise<SignerRequestDto> {\n return this.request<SignerRequestDto>(\"/api/signer-request\", {\n method: \"POST\",\n body: JSON.stringify({\n network,\n transactions,\n dAppMetadata: metadata,\n }),\n });\n }\n\n async getRequestStatus(id: string): Promise<SignerRequestStatusDto> {\n return this.request<SignerRequestStatusDto>(`/api/signer-request/${id}/status`, { method: \"GET\" });\n }\n\n async getRequest(id: string): Promise<SignerRequestDto> {\n return this.request<SignerRequestDto>(`/api/signer-request/${id}`, { method: \"GET\" });\n }\n\n async rejectRequest(id: string): Promise<void> {\n await this.request(`/api/signer-request/${id}/reject`, { method: \"POST\" });\n }\n\n async createSignMessageRequest(\n network: WalletNetwork,\n message: string,\n receiver: string,\n nonce: number[],\n callbackUrl?: string,\n metadata?: NearMobileMetadata,\n ): Promise<SignMessageRequestDto> {\n return this.request<SignMessageRequestDto>(\"/api/signer-request/message\", {\n method: \"POST\",\n body: JSON.stringify({\n network,\n message,\n receiver,\n nonce,\n callbackUrl,\n receiverMetadata: metadata,\n }),\n });\n }\n\n async getSignMessageRequest(id: string): Promise<SignMessageRequestDto> {\n return this.request<SignMessageRequestDto>(`/api/signer-request/message/${id}`, { method: \"GET\" });\n }\n\n async rejectSignMessageRequest(id: string): Promise<void> {\n await this.request(`/api/signer-request/message/${id}/reject`, { method: \"POST\" });\n }\n}\n\nconst normalizeTransactions = (\n signerId: string | undefined,\n transactions: Array<{ receiverId: string; actions: ConnectorActionLike[]; signerId?: string }>,\n): Array<{ signerId: string; receiverId: string; actions: ConnectorActionLike[] }> => {\n return transactions.map((tx) => {\n const useSigner = tx.signerId ?? signerId;\n if (useSigner == null) throw new TransportError(\"MISSING_SIGNER_ID\", \"Missing signer id for transaction\");\n return {\n signerId: useSigner,\n receiverId: tx.receiverId,\n actions: tx.actions,\n };\n });\n};\n\nexport const createNearMobileAdapter = (options: NearMobileAdapterOptions = {}) => {\n const storage = options.storage ?? createDefaultStorage();\n const session = new SessionRepository(storage);\n const backendUrl = options.signerBackendUrl ?? DEFAULT_SIGNER_BACKEND_URL;\n const nearMobileWalletUrl = options.nearMobileWalletUrl ?? DEFAULT_NEAR_MOBILE_WALLET_URL;\n const api = new NearMobileApiClient(backendUrl, options.fetcher);\n const rpcForNetwork = createRpcFactory(options.getNetworkProviders);\n const polling = { ...defaultPollingOptions, ...(options.polling ?? {}) };\n\n const emitError = (error?: Error) => options.onError?.(error);\n const emitRequested = (payload: {\n id: string;\n kind: \"request\" | \"message\";\n network: WalletNetwork;\n request: unknown;\n close: () => Promise<void>;\n }) => {\n options.onRequested?.({\n ...payload,\n requestUrl: `${nearMobileWalletUrl}/${payload.kind}/${payload.id}`,\n });\n };\n\n const awaitRequestStatus = async (id: string): Promise<SignerRequestStatusDto> => {\n return visibilityAwarePoll(\n () => api.getRequestStatus(id),\n ({ status }) => status === \"pending\",\n polling,\n );\n };\n\n const awaitMessageStatus = async (id: string): Promise<SignMessageRequestDto> => {\n return visibilityAwarePoll(\n () => api.getSignMessageRequest(id),\n ({ status, response }) => status === \"pending\" && response == null,\n polling,\n );\n };\n\n const handleRejectedStatus = (status: SignerRequestStatus, message: string): void => {\n if (status === \"approved\") {\n options.onApproved?.();\n return;\n }\n if (status === \"rejected\") {\n throw new UserRejectedError(\"USER_REJECTED\", message);\n }\n };\n\n const ensureFullAccessKey = async (network: WalletNetwork, accountId: string, publicKey: string): Promise<void> => {\n const rpc = rpcForNetwork(network);\n const accessKey = await rpc.query<any>({\n request_type: \"view_access_key\",\n finality: \"optimistic\",\n account_id: accountId,\n public_key: publicKey,\n });\n\n if (accessKey?.permission !== \"FullAccess\") {\n throw new TransportError(\"INVALID_ACCESS_KEY\", \"Signer key is not a full access key\");\n }\n };\n\n const getAccounts = async (network: WalletNetwork): Promise<WalletAccount[]> => {\n const net = ensureNetwork(network);\n const accountIds = await session.getAccounts(net);\n const accounts: WalletAccount[] = [];\n\n for (const accountId of accountIds) {\n const privateKey = await session.getKey(net, accountId);\n accounts.push({\n accountId,\n publicKey: publicKeyFromPrivate(privateKey),\n });\n }\n\n return accounts;\n };\n\n const signIn = async ({ network, contractId, methodNames = [], allowance }: SignInParams): Promise<WalletAccount[]> => {\n const net = ensureNetwork(network);\n const privateKey = privateKeyFromRandom();\n const publicKey = publicKeyFromPrivate(privateKey);\n\n const permission =\n contractId != null\n ? {\n receiverId: contractId,\n methodNames,\n ...(allowance ? { allowance } : {}),\n }\n : \"FullAccess\";\n\n const { id, network: responseNetwork, requests } = await api.createRequest(\n net,\n [\n {\n actions: [\n {\n type: \"AddKey\",\n params: {\n publicKey,\n accessKey: {\n permission,\n },\n },\n },\n ],\n },\n ],\n options.metadata,\n );\n\n emitRequested({\n id,\n kind: \"request\",\n network: responseNetwork,\n request: requests,\n close: async () => api.rejectRequest(id),\n });\n\n const { status } = await awaitRequestStatus(id);\n handleRejectedStatus(status, \"User rejected Near Mobile sign-in\");\n\n const request = await api.getRequest(id);\n if (request.signerAccountId == null) {\n throw new TransportError(\"REQUEST_NOT_SIGNED\", \"Signer request was approved but did not return signer account id\");\n }\n\n await session.setKey(net, request.signerAccountId, privateKey);\n await session.setActiveAccount(net, request.signerAccountId);\n\n options.onSuccess?.();\n return getAccounts(net);\n };\n\n const signOut = async ({ network }: { network: WalletNetwork }): Promise<void> => {\n const net = ensureNetwork(network);\n const activeAccount = await session.getActiveAccount(net);\n if (activeAccount == null) return;\n\n const privateKey = await session.getKey(net, activeAccount);\n const publicKey = publicKeyFromPrivate(privateKey);\n\n const { id, network: responseNetwork, requests } = await api.createRequest(\n net,\n [\n {\n signerId: activeAccount,\n receiverId: activeAccount,\n actions: [\n {\n type: \"DeleteKey\",\n params: { publicKey },\n },\n ],\n },\n ],\n options.metadata,\n );\n\n emitRequested({\n id,\n kind: \"request\",\n network: responseNetwork,\n request: requests,\n close: async () => api.rejectRequest(id),\n });\n\n const { status } = await awaitRequestStatus(id);\n handleRejectedStatus(status, \"User rejected Near Mobile sign-out\");\n\n await session.removeKey(net, activeAccount);\n options.onSuccess?.();\n };\n\n const signAndSendTransactions = async ({\n network,\n signerId,\n transactions,\n }: SignAndSendTransactionsParams): Promise<any[]> => {\n const net = ensureNetwork(network);\n const activeAccount = signerId ?? (await session.getActiveAccount(net)) ?? undefined;\n const normalizedTransactions = normalizeTransactions(activeAccount, transactions);\n\n const { id, network: responseNetwork, requests } = await api.createRequest(net, normalizedTransactions, options.metadata);\n emitRequested({\n id,\n kind: \"request\",\n network: responseNetwork,\n request: requests,\n close: async () => api.rejectRequest(id),\n });\n\n const { status } = await awaitRequestStatus(id);\n handleRejectedStatus(status, \"User rejected Near Mobile transaction signing\");\n\n const request = await api.getRequest(id);\n if (!request.txHash || request.txHash.length === 0) {\n throw new TransportError(\"REQUEST_NOT_SIGNED\", \"Near Mobile request did not include transaction hashes\");\n }\n\n const requestSigner = request.signerAccountId ?? normalizedTransactions[0].signerId;\n const rpc = rpcForNetwork(net);\n const outcomes: any[] = [];\n for (const hash of request.txHash) {\n outcomes.push(await rpc.txStatus(hash, requestSigner, \"EXECUTED_OPTIMISTIC\"));\n }\n\n options.onSuccess?.();\n return outcomes;\n };\n\n const signAndSendTransaction = async ({\n network,\n signerId,\n receiverId,\n actions,\n }: SignAndSendTransactionParams): Promise<any> => {\n const outcomes = await signAndSendTransactions({\n network,\n signerId,\n transactions: [{ receiverId, actions, signerId }],\n });\n return outcomes[0];\n };\n\n const signMessage = async ({\n network,\n message,\n nonce,\n recipient,\n callbackUrl,\n }: SignMessageParams): Promise<{ accountId: string; publicKey: string; signature: string }> => {\n const net = ensureNetwork(network);\n const { id, network: responseNetwork } = await api.createSignMessageRequest(\n net,\n message,\n recipient,\n Array.from(nonce),\n callbackUrl,\n options.metadata,\n );\n\n emitRequested({\n id,\n kind: \"message\",\n network: responseNetwork,\n request: { message, nonce, recipient, callbackUrl },\n close: async () => api.rejectSignMessageRequest(id),\n });\n\n const result = await awaitMessageStatus(id);\n handleRejectedStatus(result.status, \"User rejected Near Mobile message signing\");\n\n if (result.response == null) {\n throw new TransportError(\"NO_SIGNATURE\", \"Near Mobile message request was approved without a signature\");\n }\n\n const { accountId, publicKey, signature } = result.response;\n const isValidSignature = verifyNep413Signature({\n publicKey,\n signature,\n message,\n nonce,\n recipient,\n callbackUrl,\n });\n\n if (!isValidSignature) {\n throw new TransportError(\"INVALID_SIGNATURE\", \"Near Mobile returned an invalid message signature\");\n }\n\n await ensureFullAccessKey(net, accountId, publicKey);\n options.onSuccess?.();\n\n return { accountId, publicKey, signature };\n };\n\n return {\n async signIn(params: SignInParams): Promise<WalletAccount[]> {\n try {\n return await signIn(params);\n } catch (error) {\n const normalized = normalizeError(error, \"SIGN_IN_FAILED\", \"Near Mobile sign-in failed\");\n emitError(normalized);\n throw normalized;\n }\n },\n\n async signOut({ network }: { network: WalletNetwork }): Promise<void> {\n try {\n return await signOut({ network });\n } catch (error) {\n const normalized = normalizeError(error, \"SIGN_OUT_FAILED\", \"Near Mobile sign-out failed\");\n emitError(normalized);\n throw normalized;\n }\n },\n\n async getAccounts({ network }: { network: WalletNetwork }): Promise<WalletAccount[]> {\n try {\n return await getAccounts(network);\n } catch (error) {\n const normalized = normalizeError(error, \"GET_ACCOUNTS_FAILED\", \"Near Mobile getAccounts failed\");\n emitError(normalized);\n throw normalized;\n }\n },\n\n async signMessage(params: SignMessageParams): Promise<{ accountId: string; publicKey: string; signature: string }> {\n try {\n return await signMessage(params);\n } catch (error) {\n const normalized = normalizeError(error, \"SIGN_MESSAGE_FAILED\", \"Near Mobile signMessage failed\");\n emitError(normalized);\n throw normalized;\n }\n },\n\n async signAndSendTransaction(params: SignAndSendTransactionParams): Promise<any> {\n try {\n return await signAndSendTransaction(params);\n } catch (error) {\n const normalized = normalizeError(error, \"SIGN_TX_FAILED\", \"Near Mobile signAndSendTransaction failed\");\n emitError(normalized);\n throw normalized;\n }\n },\n\n async signAndSendTransactions(params: SignAndSendTransactionsParams): Promise<any[]> {\n try {\n return await signAndSendTransactions(params);\n } catch (error) {\n const normalized = normalizeError(error, \"SIGN_TXS_FAILED\", \"Near Mobile signAndSendTransactions failed\");\n emitError(normalized);\n throw normalized;\n }\n },\n };\n};\n"],"mappings":"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","names":["borshSerialize"]}