Automatically create on-chain attestations for contributors when pull requests are merged, using the Intuition Protocol.
- Creates on-chain attestations for ALL commit authors in merged PRs
- Supports both Intuition testnet and mainnet
- Handles contributors without GitHub profiles using commit metadata
- Batch operations for gas efficiency
- Configurable error handling (fail or warn mode)
- Comprehensive logging of transactions, costs, and atom IDs
- Waits for blockchain confirmations before proceeding
Add this workflow to your repository at
.github/workflows/contributor-attestation.yml:
name: Contributor Attestation
on:
pull_request:
types: [closed]
jobs:
attest:
if: github.event.pull_request.merged == true
runs-on: ubuntu-latest
steps:
- name: Create Contributor Attestations
uses: 0xIntuition/intuition-github-action@v1
with:
private-key: ${{ secrets.INTUITION_PRIVATE_KEY }}
network: 'testnet'
failure-mode: 'warn'- INTUITION_PRIVATE_KEY: Private key for signing blockchain transactions
- Generate a new wallet specifically for this action
- Fund the wallet with enough tokens for gas and attestation deposits
- Never commit or expose this key - only add it to GitHub secrets
To add the secret:
- Go to your repository Settings → Secrets and variables → Actions
- Click "New repository secret"
- Name:
INTUITION_PRIVATE_KEY - Value: Your wallet's private key (format:
0x...)
| Input | Required | Default | Description |
|---|---|---|---|
private-key |
Yes | - | Private key for signing transactions |
network |
No | testnet |
Network to use: testnet or mainnet |
failure-mode |
No | warn |
How to handle errors: fail or warn |
min-deposit-amount |
No | Auto (0.001 testnet, 0.01 mainnet) | Minimum deposit in TRUST tokens (wei) |
github-token |
No | Auto | GitHub API token (automatically provided) |
retry-attempts |
No | 3 |
Number of retry attempts for network operations |
retry-delay |
No | 2000 |
Delay between retries in milliseconds |
| Output | Description |
|---|---|
project-atom-id |
Vault ID of the project atom |
contributor-count |
Number of contributors processed |
attestations-created |
Count of new attestations created |
attestations-updated |
Count of existing attestations updated |
transaction-hashes |
JSON array of transaction hashes |
total-cost |
Total cost in TRUST tokens (wei) |
- name: Create Contributor Attestations
uses: 0xIntuition/intuition-github-action@v1
with:
private-key: ${{ secrets.INTUITION_MAINNET_PRIVATE_KEY }}
network: 'mainnet'
failure-mode: 'fail'
min-deposit-amount: '100000000000000000' # 0.1 TRUST- name: Create Contributor Attestations
id: attestation
uses: 0xIntuition/intuition-github-action@v1
with:
private-key: ${{ secrets.INTUITION_PRIVATE_KEY }}
network: 'testnet'
- name: Display Results
run: |
echo "Project Atom: ${{ steps.attestation.outputs.project-atom-id }}"
echo "Contributors: ${{ steps.attestation.outputs.contributor-count }}"
echo "Created: ${{ steps.attestation.outputs.attestations-created }}"
echo "Updated: ${{ steps.attestation.outputs.attestations-updated }}"
echo "Total Cost: ${{ steps.attestation.outputs.total-cost }} wei"When a pull request is merged, this action:
- Fetches repository metadata - Name, description, and URL
- Identifies all contributors - Extracts all commit authors from the PR
- Creates project atom - On-chain representation of the repository
- Creates contributor atoms - On-chain representations of each contributor
- Creates attestation triples - Links contributors to the project using the "was associated with" predicate
- Handles existing data - Adds deposits to existing atoms/triples instead of recreating
Each attestation creates a triple:
[Contributor Atom] --[was associated with]--> [Project Atom]
- Subject: Contributor (GitHub profile or commit author data)
- Predicate: "was associated with" (ID:
0x4ca4033b5e5e3e274225a9145170a0183f0a9ebe6ba7c4b28cce5e8cf536674c) - Object: Repository
- Get test tTRUST tokens from the Intuition Testnet faucet
- tTRUST is used for both gas fees and attestation deposits
- Fund wallet with TRUST tokens for gas and attestation deposits
Cost Estimation:
- Each atom creation: ~0.001-0.01 TRUST (tTRUST on testnet)
- Each triple creation: ~0.001-0.01 TRUST (tTRUST on testnet)
- Plus gas costs (paid in TRUST/tTRUST)
For a PR with 3 contributors:
- 1 project atom (if new)
- 3 contributor atoms (if new)
- 3 attestation triples
- Estimated: 0.007-0.07 TRUST/tTRUST total (gas + deposits)
warn mode (default):
- Logs warnings for failures
- Continues processing other contributors
- Workflow succeeds even if some attestations fail
fail mode:
- Stops on first error
- Fails the entire workflow
- Use for critical attestation requirements
-
Insufficient Balance
- Error:
Insufficient balance - Solution: Fund the wallet with more TRUST/tTRUST tokens from the faucet
- Error:
-
Network Errors
- Automatically retried with exponential backoff
- Configure
retry-attemptsandretry-delayif needed
-
GitHub API Rate Limits
- Automatically handled with retries
- Use a GitHub token with higher limits if needed
This action is built with TypeScript and uses:
- @0xintuition/sdk - High-level Intuition Protocol software development kit (SDK)
- @0xintuition/protocol - Contract ABIs and addresses
- viem - Ethereum library
- @actions/core - GitHub Actions toolkit
# Install dependencies
npm install
# Run tests
npm test
# Build and bundle
npm run bundle
# Format code
npm run format:write
# Lint
npm run lint
# Run all checks
npm run all# Create a .env file with test configuration
echo "INPUT_PRIVATE-KEY=0x..." > .env
echo "INPUT_NETWORK=testnet" >> .env
echo "INPUT_GITHUB-TOKEN=$GITHUB_TOKEN" >> .env
# Run locally
npm run local-actionThe project includes comprehensive integration tests that make real network calls to Intuition Testnet:
# Setup (one-time)
cp .env.integration.example .env.local
# Edit .env.local with your test wallet private key
# Run integration tests
npm run test:integration
# Run specific test file
npm run test:integration -- client.integration.test.ts
# Run in watch mode
npm run test:integration:watchImportant Notes:
- Integration tests create actual on-chain transactions
- Tests cost testnet tTRUST tokens (gas and deposits)
- Tests take 20-30 minutes to complete
- Tests are excluded from CI and
npm test - See
__tests__/integration/README.mdfor detailed setup instructions
Test Coverage:
- ✅ Real client initialization and balance checking
- ✅ Atom creation on Intuition Testnet
- ✅ Triple creation and deposits
- ✅ End-to-end attestation flows
- ✅ Cost tracking and transaction verification
An automated test workflow runs after PRs merge to main to validate the action in a real-world scenario:
Workflow: .github/workflows/test-attestation-post-merge.yml
Behavior:
- Triggers automatically when PRs are merged to main
- Runs the action against the actual merged PR
- Creates real attestations on Intuition Testnet
- Validates outputs and provides Intuition Explorer transaction links
- Non-blocking: failures don't prevent PR merges
Setup:
-
Add
INTUITION_PRIVATE_KEYsecret to repository:- Navigate to: Settings → Secrets and variables → Actions
- Create new secret:
INTUITION_PRIVATE_KEY - Use a dedicated testnet wallet (separate from production)
-
Fund the test wallet:
- Intuition Testnet native tokens (tTRUST) for gas and deposits
- Faucet: https://testnet.hub.intuition.systems/
- Recommended: 0.1 tTRUST
-
Workflow runs automatically on merge
View results: Actions tab → "Test Post-Merge Attestation"
Expected costs per PR (3 contributors):
- 0.007-0.07 tTRUST tokens (gas + deposits)
- Never commit private keys - Always use GitHub secrets
- Use dedicated wallets - Create a wallet specifically for this action
- Start with testnet - Test thoroughly before using mainnet
- Monitor wallet balance - Set up alerts for low balances
- Review transactions - Check transaction hashes in action logs
MIT
Built with the Intuition Protocol - enabling verifiable, on-chain reputation and attestations.