{"id":16253155,"url":"https://github.com/vgrichina/web4-deploy","last_synced_at":"2025-10-14T19:08:57.330Z","repository":{"id":41391262,"uuid":"504031832","full_name":"vgrichina/web4-deploy","owner":"vgrichina","description":"Deploy static content for Web4 webapp. Supports IPFS for now.","archived":false,"fork":false,"pushed_at":"2025-04-25T23:58:12.000Z","size":334,"stargazers_count":23,"open_issues_count":2,"forks_count":7,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-14T19:07:38.926Z","etag":null,"topics":["blockchain","ipfs","nearprotocol","permaweb","web3","web4"],"latest_commit_sha":null,"homepage":"https://web4.near.page","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/vgrichina.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2022-06-16T06:03:52.000Z","updated_at":"2025-08-27T13:19:58.000Z","dependencies_parsed_at":"2023-12-07T07:25:47.962Z","dependency_job_id":"bea11d04-4e02-438b-aad5-039b67639af0","html_url":"https://github.com/vgrichina/web4-deploy","commit_stats":{"total_commits":106,"total_committers":3,"mean_commits":"35.333333333333336","dds":"0.028301886792452824","last_synced_commit":"b2c399e600859f4064234e1921128ce2b26c1793"},"previous_names":[],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/vgrichina/web4-deploy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fweb4-deploy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fweb4-deploy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fweb4-deploy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fweb4-deploy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/vgrichina","download_url":"https://codeload.github.com/vgrichina/web4-deploy/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/vgrichina%2Fweb4-deploy/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":279020642,"owners_count":26086895,"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-14T02:00:06.444Z","response_time":60,"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","ipfs","nearprotocol","permaweb","web3","web4"],"created_at":"2024-10-10T15:16:08.432Z","updated_at":"2025-10-14T19:08:57.298Z","avatar_url":"https://github.com/vgrichina.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# web4-deploy\n\nDeploy static content for Web4 webapps. Supports IPFS and NEARFS.\n\nDesigned to be used together with https://github.com/vgrichina/web4.\n\n## Usage\n\n### Prerequisites\n\n- Node.js 14 or higher\n- (Optional) IPFS pinning service API key if not using NEARFS\n\n#### IPFS Pinning Services\n\nIf you want to use IPFS pinning (optional, as NEARFS is the default), two services are supported:\n\n##### web3.storage\n\n1. Go to https://web3.storage and sign up for an account or login with GitHub\n2. Go to https://web3.storage/docs/how-tos/generate-api-token/ and create a new token\n3. Set the token as `WEB3_TOKEN` environment variable before running the script\n\n\n### Deploy to IPFS\n\nWhen installed (use either npm or yarn):\n\n```sh\nweb4-deploy \u003csrc-directory\u003e \u003cdestination-account.near\u003e\n```\n\nRun latest version from npm if not installed:\n\n```sh\nnpx web4-deploy \u003csrc-directory\u003e \u003cdestination-account.near\u003e\n```\n\nDeploy default smart contract after uploading to IPFS:\n\n```sh\nnpx web4-deploy \u003csrc-directory\u003e \u003cdestination-account.near\u003e --deploy-contract\n```\n\nThis will deploy [web4-min-contract](https://github.com/vgrichina/web4-min-contract) to the account, so that `.near` account can be connected to respective IPFS hash.\n\nDeploy custom smart contract after uploading to IPFS:\n\n```sh\nnpx web4-deploy \u003csrc-directory\u003e \u003cdestination-account.near\u003e --deploy-contract path/to/contract.wasm\n```\n\n### Deploy fully on-chain to NEARFS\n\nWhen you want best availability guarantees and don't mind to pay for storage, you can deploy to [NEARFS](https://github.com/vgrichina/nearfs).\n\n```sh\nnpx web4-deploy \u003csrc-directory\u003e \u003cdestination-account.near\u003e  --nearfs\n```\n\nNote that you need to either provide `NEAR_SIGNER_KEY` or have `~/.near-credentials/\u003cnetworkId\u003e/\u003cdestination-account.near\u003e.json` file with key. Use `NEAR_ENV` or `NODE_ENV` to specify NEAR network to use. Defaults to `testnet`.\n\n### Use in CI/CD pipeline like GitHub Actions\n\nMake sure to store `WEB3_TOKEN` and `NEAR_SIGNER_KEY` as GitHub secrets.\n\n`NEAR_SIGNER_KEY` allows you to pass necessary private key to the deploy script without having key storage in `~/near-credentials` as usually required by `near-cli`.\n\nNote that you don't have to sign using destination account, account you sign for should just be accepted as valid owner by `web4_setStaticUrl` method.\n\nMeans that you can have GitHub-specific account which cannot do anything else besides updating static content.\n\n### CLI Options\n\n- `--deploy-contract [contract-name]`: Deploy contract to the account. If contract name is not provided, default contract will be deployed.\n- `--network [network]`: NEAR network ID. Default: mainnet for .near accounts, testnet otherwise.\n- `--nearfs`: Deploy to NEARFS (default storage provider)\n- `--web3-storage`: Use web3.storage for IPFS pinning instead of NEARFS\n- `--yes`: Skip confirmation prompt.\n\n### Environment Variables\n\n#### NEAR Configuration\n- `NEAR_ENV` – NEAR network to use, defaults to `testnet` (or `mainnet` for .near accounts)\n- `NODE_ENV` - can be used instead of `NEAR_ENV`\n- `NEAR_SIGNER_ACCOUNT` - Account to use for signing transactions. Defaults to destination account\n- `NEAR_SIGNER_KEY` - Private key for signing (base58-encoded, starts with 'ed25519:'). Alternative to ~/.near-credentials\n\n#### NEARFS Configuration (Default Storage)\n- `NEARFS_GATEWAY_URL` - Gateway URL. Defaults to:\n  - Mainnet: https://ipfs.web4.near.page\n  - Testnet: https://ipfs.web4.testnet.page\n- `NEARFS_GATEWAY_TIMEOUT` - Gateway request timeout in milliseconds (default: 2500)\n- `NEARFS_GATEWAY_RETRY_COUNT` - Maximum gateway retry attempts (default: 3)\n\n#### IPFS Configuration (Optional)\n- `WEB3_TOKEN` - web3.storage API token\n- `IPFS_GATEWAY_LIST` - Comma-separated list of IPFS gateways to check (default: cloudflare-ipfs.com)\n- `IPFS_CHECK_DELAY` - Delay in milliseconds between gateway retries (default: 15000)\n\n## Testing\n\nTo run the test suite:\n\n```sh\nyarn test\n```\n\nThe test suite includes unit tests for:\n- Contract deployment\n- Gateway checking\n- NEARFS integration\n- CLI functionality\n- User confirmation handling\n\n## Development\n\n### WebAssembly Contract Diffs\n\nThe repository includes WebAssembly diff support to make contract changes more visible. To enable this feature, install the WebAssembly Binary Toolkit (WABT):\n\n```bash\n# Ubuntu/Debian\nsudo apt install wabt\n# macOS\nbrew install wabt\n```\n\nThis allows you to see readable diffs when the default contract (`data/web4-min.wasm`) changes.\n\n## How it works\n\nThe deployment process consists of these steps:\n\n1. Your static content is packaged into a CAR (Content Addressable aRchive) file\n2. The content is deployed using one of these methods:\n   - NEARFS (default) - stores content directly on NEAR blockchain\n   - web3.storage - pins content to IPFS network\n3. The smart contract's `web4_setStaticUrl` method is called to update the content URL\n\nThe default [web4-min-contract](https://github.com/vgrichina/web4-min-contract) provides these key features:\n\n### Single Page Application (SPA) Support\nThe contract automatically handles SPAs by redirecting paths without file extensions to `index.html`. For example:\n- `/about` -\u003e serves `/index.html`\n- `/style.css` -\u003e serves directly\n\n### Default Content\nWhen no static URL is set (before first deployment), the contract serves default content from IPFS with getting started instructions.\n\n### Access Control\nThe contract can be managed by either:\n- The contract account itself\n- An owner account (if set via web4_setOwner)\n\nThis means you can:\n- Use the contract account's full access key (stored in ~/.near-credentials)\n- Use NEAR_SIGNER_KEY environment variable\n- Set up a separate owner account for content management\n\n## Smart contract integration\n\nYou need to implement `web4_setStaticUrl` method similar to this:\n\n```ts\nfunction assertOwner(): void {\n    // NOTE: Can change this check to allow different owners\n    assert(context.sender == context.contractName);\n}\n\nconst WEB4_STATIC_URL_KEY = 'web4:staticUrl';\n\n// Updates current static content URL in smart contract storage\nexport function web4_setStaticUrl(url: string): void {\n    assertOwner();\n\n    storage.set(WEB4_STATIC_URL_KEY, url);\n}\n```\n\nThen in `web4_get` you can return static URL to be fetched:\n\n```ts\n// Demonstrate serving content from IPFS\nif (request.path == \"/\") {\n    return bodyUrl(`${storage.getString(WEB4_STATIC_URL_KEY)!}${request.path}`);\n}\n\n```\n\nThis allows to update static content without redeploying smart contract, which results in faster and safer deploys.\n\nSee example smart contract: https://github.com/vgrichina/web4/blob/main/contract/assembly/index.ts\n\nYou can also use default smart contract for reference: [web4-min-contract](https://github.com/vgrichina/web4-min-contract)\n\n## Roadmap\n\n- [x] Make sure every uploaded file is hot on IPFS gateways\n- [x] Deploy default smart contract with `web4_setStaticUrl` method\n- [x] Allow to pass NEAR account and private key in environment variables\n- [ ] More robust CLI interface with both options and environment variables support\n- [x] Deploy static website to NEAR account and NEARFS via single simple interactive command\n- [ ] Automatically login without having to install near-cli\n- [ ] Allow to create web4. subaccount automatically\n- [x] Support testnet for NEARFS\n- [x] Allow storing files directly on chain\n- [ ] Support other storage providers?\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvgrichina%2Fweb4-deploy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fvgrichina%2Fweb4-deploy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fvgrichina%2Fweb4-deploy/lists"}