sign-free.openapps.xyz

Source

This app’s code and revision history are public. Download a copy or explore the files below.

Public
The app’s code and revision history are public.
Owned app · rev 528326727848
Run it yourself
Take the whole tree and run it on your own machine. The download needs no account. Cloning needs a sign-in.
Download .zip
bounded clone 1da91c033c738ab74538d13d
A copy you download is not bounded. The guarantees this app runs under - declared egress, proven invariants, writes that fail closed - live in the runtime serving this page, not in the files. What you get is auditable source you can read and run, with no runtime guarantees attached.
← All files
AGENTS.md
# Sign

Sign is a free e-signature app, and a free alternative to DocuSign, Dropbox Sign and Adobe Acrobat Sign. It is an OpenApp in the OpenApps free apps store (https://free-apps.openapps.xyz/), owned by the OpenApps team.

## What it promises

- Free, with no limit on documents or signers, no ads and no paid tier. Never add a cap, an upsell or tracking.
- No sign-up for anyone. Every visitor is a guest account created in the browser.
- A record that holds up: signer consent, an audit trail (created, sent, opened, signed, voided) and the original document's SHA-256 fingerprint, all printed on the completion certificate of the signed PDF.
- AI assistants can send text documents for signature through the public API (`functions/api.ts`), documented in `public/llms.txt` and `public/openapi.json`. Keep both true whenever the API changes, and keep `public/index.md` (the landing page in plain markdown) in step with `index.html`.

## How it is built

- `index.html` is the static landing page that search engines and AI crawlers read. Keep its copy, FAQ and JSON-LD in sync with what the app does.
- `src/` is the React app. `/` mounts the start box and "Your documents" into the landing; `/new` writes a text document (`/new#title=...&text=...` prefills it, for assistants); `/d/<id>` is the owner's page (prepare, send, follow, download, make a copy, void); `/s/<docId>/<signerId>#t=<token>` is a signer's page. The owner can open any signer's page on their own device ("Sign on this device"), which is how people sign their own documents.
- The landing stays light: `src/Home.tsx` imports no data client or PDF library; `src/lib/actions.ts` (creating, copying, list statuses) loads on first use. Keep it that way.
- `src/lib/mydocs.ts` is the "Your documents" list with admin keys, kept in this browser only.
- Shared UI is in `src/ui.tsx` (dialog with exit animation, menu, toast, offline notice) on top of the kit in `public/kit.css`; `src/Skeleton.tsx` holds the loading shapes.
- PDFs are uploaded to Bounded storage (`docfiles/<id>/f/original`). Text documents store only their text: `src/lib/textpdf.ts` renders the same pages and signature fields from it everywhere, deterministically. Changing that renderer changes how existing text documents look, so keep it stable.
- `src/lib/finalpdf.ts` builds the signed PDF in the browser: the signers' values drawn on the original pages (honoring page rotation), then the certificate.
- `policy.json` holds the rules:
  - Owners: the creator, or anyone presenting the admin key (`dockeys`, claimed through `docclaims`). The admin link carries the key in the URL fragment.
  - Signers: a device joins as a signer (`signerjoins`) by presenting that signer's token (`signertokens`, claimed through `signerclaims`). A signing link carries the token in the fragment.
  - Once a document is sent its text, signers and fields cannot change. A signature is written once and never changed, only by the joined signer, only with consent, only while the document is sent.
  - A document is complete when every signer has a signature; nothing stores "completed".
  - `dockeys` and `signertokens` are readable by owners and by the API's public principal (`@const.BOUNDED_PUBLIC_PRINCIPAL_API`), which checks owner keys for assistants.
- `functions/lib/doc.ts` is shared by the app and the API. `functions/lib/config.ts` holds the app id and the site URL used in links.

## Working on it

`npm install && npm run build` typechecks and builds `dist/`. Ship changes through previews and releases as your runtime instructions describe; the app is an OpenApp, so nobody deploys it directly.

Check a change end to end at 390px and 1440px: upload a PDF, add two signers, place fields (including on a rotated page, and from the keyboard), label a text field, send, sign from both links in separate browsers (one of them with "Sign on this device"), and download the signed PDF; make a copy; then the same through the API with a text document.

## Voice

Plain words, short sentences, no jargon, no em dashes. Say what happens, not how clever it is.

Change history

Quality pass: phone signing, edit signers, copy to send again
5283267278 · 5 hours ago
Bounded source sync
15f0fa2e27 · 1 day ago
Bounded source sync
d3aa1ca65b · 1 day ago
Bounded source sync
8e2ca0b773 · 1 day ago
Bounded source sync
5cfa84715c · 1 day ago
Bounded source sync
c849e7b286 · 1 day ago
Bounded source sync
68c1cabe03 · 1 day ago
Bounded source sync
62ae8944f0 · 1 day ago
Bounded source sync
7ed54e7381 · 1 day ago