{"id":49580650,"url":"https://github.com/retyc/retyc-ts-sdk","last_synced_at":"2026-05-03T19:09:19.295Z","repository":{"id":355002304,"uuid":"1220641059","full_name":"retyc/retyc-ts-sdk","owner":"retyc","description":"Retyc TypeScript SDK","archived":false,"fork":false,"pushed_at":"2026-05-01T10:49:03.000Z","size":79,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"master","last_synced_at":"2026-05-01T12:22:17.037Z","etag":null,"topics":["age-encryption","end-to-end-encryption","file-transfer","retyc","sdk-typescript","zero-knowledge"],"latest_commit_sha":null,"homepage":"https://retyc.com","language":"TypeScript","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/retyc.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":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-04-25T06:17:08.000Z","updated_at":"2026-05-01T10:49:08.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/retyc/retyc-ts-sdk","commit_stats":null,"previous_names":["retyc/retyc-ts-sdk"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/retyc/retyc-ts-sdk","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/retyc%2Fretyc-ts-sdk","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/retyc%2Fretyc-ts-sdk/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/retyc%2Fretyc-ts-sdk/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/retyc%2Fretyc-ts-sdk/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/retyc","download_url":"https://codeload.github.com/retyc/retyc-ts-sdk/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/retyc%2Fretyc-ts-sdk/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32581161,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-03T06:36:36.687Z","status":"ssl_error","status_checked_at":"2026-05-03T06:36:09.306Z","response_time":103,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"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":["age-encryption","end-to-end-encryption","file-transfer","retyc","sdk-typescript","zero-knowledge"],"created_at":"2026-05-03T19:09:18.660Z","updated_at":"2026-05-03T19:09:19.284Z","avatar_url":"https://github.com/retyc.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003cp align=\"center\"\u003e\u003cimg width=\"200\" src=\"https://raw.githubusercontent.com/retyc/retyc-ts-sdk/master/.media/Retyc_Logo_Blue.png\" alt=\"Retyc logo\" /\u003e\u003c/p\u003e\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://github.com/retyc/retyc-ts-sdk/actions/workflows/ci.yml\"\u003e\u003cimg src=\"https://github.com/retyc/retyc-ts-sdk/actions/workflows/ci.yml/badge.svg\" alt=\"CI\" /\u003e\u003c/a\u003e\n  \u003ca href=\"https://github.com/retyc/retyc-ts-sdk/releases/latest\"\u003e\u003cimg src=\"https://img.shields.io/github/v/release/retyc/retyc-ts-sdk\" alt=\"Release\" /\u003e\u003c/a\u003e\n  \u003ca href=\"LICENSE\"\u003e\u003cimg src=\"https://img.shields.io/badge/license-MIT-blue.svg\" alt=\"License: MIT\" /\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n# Retyc TypeScript SDK\n\n\u003e Official TypeScript SDK for [Retyc](https://retyc.com) — manage file transfers programmatically\n\n---\n\n## What is Retyc?\n\n[Retyc](https://retyc.com) is a European sovereign file-sharing platform with end-to-end post-quantum encryption. Data stays in Europe, GDPR-compliant by design.\n\n`@retyc/sdk` lets you integrate Retyc transfers into your scripts, pipelines and workflows — no browser required.\n\n---\n\n## Installation\n\n```bash\nnpm install @retyc/sdk\n# or\npnpm add @retyc/sdk\n# or\nyarn add @retyc/sdk\n```\n\n---\n\n## Usage\n\n### Initialize the client\n\n```ts\nimport { RetycSDK, FileTokenStore } from '@retyc/sdk'\n\nconst sdk = new RetycSDK({\n  apiUrl: 'https://api.retyc.com',\n  // Persist tokens across restarts (optional, defaults to in-memory)\n  tokenStore: new FileTokenStore('/home/user/.retyc/tokens.json'),\n})\n```\n\n---\n\n### Authentication (Device Flow)\n\nRetyc uses the OAuth 2.0 Device Authorization Grant. The user authenticates in their browser while your script polls for the token.\n\n```ts\n// Start the device flow\nconst flow = await sdk.auth.startDeviceFlow()\n\n// Show the user where to authenticate\nconsole.log(`Open ${flow.verificationUri} and enter code: ${flow.userCode}`)\n// Or use the direct link if available:\n// console.log(`Or visit: ${flow.verificationUriComplete}`)\n\n// Wait until the user completes authentication\nconst tokens = await flow.poll()\n\nconsole.log('Authenticated! Access token expires at:', tokens.expiresAt)\n```\n\n#### Reloading an existing session\n\nIf tokens were persisted (e.g. via `FileTokenStore`), the SDK auto-refreshes them on the first request — no extra setup needed.\n\n```ts\nconst tokens = await sdk.auth.getTokens()\nif (!tokens) {\n  // Run device flow...\n}\n```\n\nOptionally, call `preload()` once on startup to pre-fetch the OIDC config and avoid latency on the first refresh:\n\n```ts\nawait sdk.preload()\n```\n\n#### Manual refresh\n\nThe SDK refreshes tokens automatically when needed (on expiry or on a 401). You can also force a refresh manually:\n\n```ts\nconst tokens = await sdk.auth.refresh()\n```\n\n#### Logout\n\n```ts\nawait sdk.auth.logout()\n```\n\n---\n\n### User\n\n```ts\n// Fetch the authenticated user's profile\nconst { user, extra_data, roles } = await sdk.user.getMe()\nconsole.log(user.email, user.full_name, roles)\n\n// Fetch the active age keypair (encrypted private key + public key)\nconst key = await sdk.user.getActiveKey()\nconsole.log(key.public_key, key.status) // status: 'active' | 'pending' | 'revoked'\n```\n\n---\n\n### Transfers\n\n#### Upload\n\n```ts\nimport { readFileSync, statSync } from 'node:fs'\n\nconst result = await sdk.transfers.upload({\n  recipients: ['alice@example.com', 'bob@example.com'],\n  title: 'Q1 Report',\n  expires: 7, // days\n  files: [\n    {\n      name: 'report.pdf',\n      mimeType: 'application/pdf',\n      data: readFileSync('./report.pdf'),\n      size: statSync('./report.pdf').size,\n    },\n  ],\n})\n\nconsole.log('Transfer created:', result.transferId)\nconsole.log('Share link: https://retyc.com/share/' + result.slug)\n```\n\n#### Download\n\nDownloading requires two steps: resolve the transfer session key, then download the files.\n\n#### With a Retyc account (private key)\n\n```ts\nimport { writeFileSync } from 'node:fs'\nimport { decryptStringWithPassphrase } from '@retyc/sdk'\n\n// 1. Fetch your encrypted private key and unlock it with your key password\nconst { private_key_enc } = await sdk.user.getActiveKey()\nconst privateKey = await decryptStringWithPassphrase(private_key_enc!, 'your-key-password')\n\n// 2. Resolve the transfer session key\nconst sessionKey = await sdk.transfers.resolveSessionKey('transfer-id', { privateKey })\n\n// 3. Download and decrypt files\nconst files = await sdk.transfers.download('transfer-id', sessionKey)\n\nfor (const file of files) {\n  writeFileSync(file.name, file.data!)\n}\n```\n\n#### Without an account (transfer passphrase)\n\nWhen the sender protected the transfer with a passphrase, no account key is needed.\n\n```ts\nconst sessionKey = await sdk.transfers.resolveSessionKey('transfer-id', {\n  transferPassphrase: 'the-passphrase-shared-by-the-sender',\n})\n\nconst files = await sdk.transfers.download('transfer-id', sessionKey)\n```\n\n#### Streaming to disk (large files)\n\nBy default files are buffered in memory (`file.data: Buffer`). For large transfers, pass `outputPath` to stream directly to disk — `file.data` will be `null`.\n\n```ts\nconst files = await sdk.transfers.download('transfer-id', sessionKey, {\n  outputPath: '/tmp/retyc-downloads',\n})\n\nfor (const file of files) {\n  console.log(`Saved ${file.name} (${file.size} bytes)`)\n}\n```\n\nThe output directory is created automatically. File names containing `..` or starting with `/` are rejected.\n\n#### Manage transfers\n\n```ts\n// Disable a transfer (recipients can no longer access it)\nawait sdk.transfers.disable('transfer-id')\n\n// Permanently delete a transfer and all its files\nawait sdk.transfers.forceDelete('transfer-id')\n```\n\n---\n\n## API Reference\n\n### `new RetycSDK(config)`\n\n| Option | Type | Default | Description |\n| --- | --- | --- | --- |\n| `apiUrl` | `string` | — | Retyc API base URL |\n| `tokenStore` | `TokenStore` | `InMemoryTokenStore` | Where to persist OAuth tokens |\n| `chunkSize` | `number` | `8388608` (8 MB) | Upload chunk size in bytes |\n| `uploadConcurrency` | `number` | `4` | Max concurrent chunk uploads |\n| `downloadConcurrency` | `number` | `4` | Max concurrent chunk downloads |\n\n### `sdk.auth`\n\n| Method | Returns | Description |\n| --- | --- | --- |\n| `startDeviceFlow()` | `DeviceFlowResult` | Initiate the OAuth 2.0 Device Authorization Grant. Call `.poll()` on the result to wait for the user. |\n| `refresh()` | `TokenSet` | Force a token refresh using the stored refresh token. Refreshes are otherwise triggered automatically. |\n| `getTokens()` | `TokenSet \\| null` | Read the currently stored tokens (or `null` if not authenticated). |\n| `logout()` | `void` | Clear stored tokens. |\n\n### `sdk.user`\n\n| Method | Returns | Description |\n| --- | --- | --- |\n| `getMe()` | `UserApiResponse` | Authenticated user profile + OIDC extra data + roles |\n| `getActiveKey()` | `UserKeyApiResponse` | Active age keypair (`public_key`, `private_key_enc`, `status`) |\n\n### Token stores\n\n| Class | Description |\n| --- | --- |\n| `InMemoryTokenStore` | Default. Tokens are lost when the process exits. |\n| `FileTokenStore(path)` | Persists tokens to a JSON file on disk. |\n\nYou can implement the `TokenStore` interface to use any custom storage backend (keychain, database, etc.).\n\n---\n\n## License\n\n[MIT](LICENSE) — © Retyc / TripleStack SAS\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fretyc%2Fretyc-ts-sdk","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fretyc%2Fretyc-ts-sdk","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fretyc%2Fretyc-ts-sdk/lists"}