{"id":31923312,"url":"https://github.com/fuellabs/authn-sign","last_synced_at":"2025-10-13T23:49:16.647Z","repository":{"id":206284853,"uuid":"715583661","full_name":"FuelLabs/authn-sign","owner":"FuelLabs","description":"✍️ authn-sign - A simplified browser interface for WebAuthn focused on secp256r1 (P-256).","archived":false,"fork":false,"pushed_at":"2023-11-27T13:46:24.000Z","size":2403,"stargazers_count":24,"open_issues_count":0,"forks_count":5,"subscribers_count":3,"default_branch":"master","last_synced_at":"2025-10-02T01:00:00.816Z","etag":null,"topics":["blockchain","p-256","secp256r1","webauthn"],"latest_commit_sha":null,"homepage":"https://authn-sign.vercel.app","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/FuelLabs.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2023-11-07T12:44:50.000Z","updated_at":"2025-04-22T14:31:13.000Z","dependencies_parsed_at":"2024-11-11T09:38:36.790Z","dependency_job_id":"b0944763-0705-4944-8a0b-b88936745223","html_url":"https://github.com/FuelLabs/authn-sign","commit_stats":{"total_commits":43,"total_committers":1,"mean_commits":43.0,"dds":0.0,"last_synced_commit":"e95a9dbc305256a70dfd0cc12eb2fa721c384639"},"previous_names":["fuellabs/authn-sign"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/FuelLabs/authn-sign","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuelLabs%2Fauthn-sign","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuelLabs%2Fauthn-sign/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuelLabs%2Fauthn-sign/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuelLabs%2Fauthn-sign/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/FuelLabs","download_url":"https://codeload.github.com/FuelLabs/authn-sign/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/FuelLabs%2Fauthn-sign/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279017229,"owners_count":26086016,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","status":"online","status_checked_at":"2025-10-13T02:00:06.723Z","response_time":61,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["blockchain","p-256","secp256r1","webauthn"],"created_at":"2025-10-13T23:49:15.186Z","updated_at":"2025-10-13T23:49:16.638Z","avatar_url":"https://github.com/FuelLabs.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# authn-sign\nA simplified browser interface for WebAuthn focused on secp256r1 (P-256) signing.\n\n## Features\n- `create`, `sign` (i.e. authenticate) and `recover` from WebAuthn.\n- Extremly light with minimal dependancies (just `@noble/curves`).\n- Supports compressed and non compressed public keys.\n- Supports EIP-2098 encoded and non-encoded signatures.\n- Designed for blockchain applications which typically use *prefixed hex data* encoding.\n- Suports an EIP-2098 sha based address creation using `sha256(publicKeyCompact)`.\n- Decoded `pre` and `post` challenge JSON `clientData` strings provided out of the box.\n\n*Warning: this library is in BETA, do not use it for production use.*\n\nA note that WebAuthn local testing requires HTTPS and a `localhost` non IP address.\n\nTry it now: [authn-sign.vercel.app](https://authn-sign.vercel.app).\n\n## Install\n```sh\nnpm install --save authn-sign\n```\n\n### CDN (via Module)\n```js\nimport Account from \"https://unpkg.com/authn-sign@latest/build/authn-sign.min.js\";\n```\n\n### CDN (via UMD)\n```html\n\u003cscript type=\"text/javascript\" src=\"https://unpkg.com/authn-sign@latest/build/authn-sign.umd.js\"\u003e\u003c/script\u003e\n```\n\nExport available at `window.authnSign`.\n\n## Build\n```sh\n# Install Bun.js - https://bun.sh\nbun run build\n```\nOutput is set to `./build/[name].[ext]`.\n\n## Test\n```\nbun run test\n```\n\n## Example\n```js\nimport Account from \"authn-sign\";\n\n(async () =\u003e {\n    // Create a new account.\n    const account = await Account.create(\"account_1\");\n\n    // Log the new account information.\n    console.log('Account', {\n        \"publicKey\": account.publicKey, // 65 bytes\n        \"publicKeyCompact\": account.publicKeyCompact, // 64 bytes\n        \"id\": account.id,\n    });\n\n    // The challenge (which in blockchain would be the tx id).\n    const challenge = '0xe3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855';\n\n    // Sign the challenge.\n    const signature = await account.sign(challenge /*, options */);\n\n    // Log the signature payload (includes pre/post client data, signature, digest and other items).\n    console.log('Signature', signature);\n})();\n```\n\n### Account Recovery\n```js\nimport Account from \"authn-sign\";\n\n// Dual signature account recovery.\nconst account = await Account.recover();\n\n// Log the recovered account.\nconsole.log(account.id);\n```\n\n### Hosted Wallet Example:\n[authn-sign.vercel.app/](https://authn-sign.vercel.app)\n\n### Simple Example:\n[authn-sign.vercel.app/simple.html](https://authn-sign.vercel.app/simple.html)\n\n## Blockchain Verification Check (in NodeJS)\n```js\n// This would happen in the browser.\nconst account = new Account();\nawait account.create('username_1');\nconst transaction_hash = '0xb4f62ae3e337421868782a88ff7d81a8bf44ef6722dfcd0c70d08a0adc25663d';\nconst signature = await account.sign(account, transaction_hash);\n\n// This would happen on chain.\nconst signedData = signature.clientData.preChallenge \n  + utils.hexToBase64(transaction_hash).slice(0, -1) // remove last character\n  + signature.clientData.postChallenge;\nconst clientDataHash = utils.bufferToHex(await utils.sha256(utils.toBuffer(signedData)));\nconst message = utils.concatHexStrings(signature.authenticatorData, clientDataHash);\n// const messageHash = utils.bufferToHex(await utils.sha256(message));\n\n// This P-256 verficiation would also happen on chain.\nconst is_verified = await verify({\n  publicKey: account.publicKey,\n  message: utils.bufferToHex(message),\n  signature: signature.signature,\n});\n\nconsole.log(is_verified);\n```\n\n## Size\n```\nauthn-sign.min.js        35.44 KB\nauthn-sign.js        63.70 KB\n```\n\n## Exports\n```ts\nexport declare function toBuffer(txt: string): ArrayBuffer;\nexport declare function parseBuffer(buffer: ArrayBuffer): string;\nexport declare function isBase64url(txt: string): boolean;\nexport declare function toBase64url(buffer: ArrayBuffer): string;\nexport declare function parseBase64url(txt: string): ArrayBuffer;\nexport declare function sha256(buffer: ArrayBuffer | Uint8Array): Promise\u003cArrayBuffer\u003e;\nexport declare function concatenateBuffers(buffer1: ArrayBuffer, buffer2: ArrayBuffer): Uint8Array;\nexport declare function convertASN1toRaw(signatureBuffer?: {}): Uint8Array;\nexport declare function hexToBuffer(value: string): ArrayBuffer;\nexport declare function parseHexString(value: string): ArrayBuffer;\nexport declare function parseCryptoKey(publicKey: string): Promise\u003cany\u003e;\nexport declare function bufferToHex(buffer: ArrayBuffer | Uint8Array): string;\nexport declare function cryptoKeyToHex(cryptoKey: any): Promise\u003cstring\u003e;\nexport declare function base64ToHex(value: string): string;\nexport declare function hexToBase64(value: string): string;\nexport declare function concatHexStrings(value1: string, value2: string): ArrayBuffer;\nexport declare const windowObject: any;\nexport declare const navigatorObject: any;\nexport declare function encode_signature(signatureCompact?: string, recovery_id?: number): string;\nexport declare function decode_signature(signatureCompact?: string): any;\nexport declare function removeBase64Padding(data: string): string;\nexport declare function clientDataToJSON(clientData: string): any;\nexport declare function simulate_onchain_verification(publicKey?: string, publicKeyCompact?: string, address?: string, authdata?: string, pre?: string, challenge?: string, post?: string, signature?: string): Promise\u003cboolean\u003e;\nexport default class Account {\n    #private;\n    get id(): string;\n    get username(): string;\n    get publicKey(): string;\n    get publicKeyCompact(): string;\n    address(): Promise\u003cstring\u003e;\n    /**\n     *  The ```constructor``` method for constructing an account.\n     *\n     *  This allows you to recover an account from a DB to use for authorization.\n     */\n    constructor(username: string, id: string, pulicKey: string, options?: any);\n    /**\n     *  The ```create``` method for signature.\n     *\n     *  This is the primary account register function for WebAuthn.\n     */\n    static create(username: string, options?: any): Promise\u003cAccount\u003e;\n    /**\n     *  The ```sign``` authorization signing method.\n     *\n     *  This uses authorization under the hood to sign a message.\n     */\n    sign(challenge?: string, options?: any): Promise\u003cany\u003e;\n    /**\n     *  ```recover``` an account from two WebAuthn signatures (dual signature recovery).\n     *\n     *  This allows a user to recover their WebAuthn account (we need this because WebAuthn doesn't return a public key during the signing process).\n     */\n     static async recover(username = 'username_1', options:any = {}): Promise\u003cAccount\u003e;\n}\nexport declare function recover(signature?: string, message?: string, recoveryBit?: number): string;\nexport declare function normalizeSignature(signature?: string, digest?: string, publicKeyCompact?: string): string;\n```\n\n## Todo\n- Nits and cleanup for encoding.\n- More protective measures against bad values (assertHex etc.).\n- Better typing structures (e.g. PublicKey, Signature, CreationOption etc.).\n- Make optional the dependancy on node/browser crypto module.\n- Final API is still being decided so leave your feedback as an issue!\n\n## Licence\n```\nMIT License\n\nCopyright (c) 2023 Fuel Labs Inc.\n\nPermission is hereby granted, free of charge, to any person obtaining a copy\nof this software and associated documentation files (the \"Software\"), to deal\nin the Software without restriction, including without limitation the rights\nto use, copy, modify, merge, publish, distribute, sublicense, and/or sell\ncopies of the Software, and to permit persons to whom the Software is\nfurnished to do so, subject to the following conditions:\n\nThe above copyright notice and this permission notice shall be included in all\ncopies or substantial portions of the Software.\n\nTHE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR\nIMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,\nFITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE\nAUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER\nLIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,\nOUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE\nSOFTWARE.\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuellabs%2Fauthn-sign","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffuellabs%2Fauthn-sign","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffuellabs%2Fauthn-sign/lists"}