Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/publish-abi.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
name: publish-abi

on:
push:
tags:
- 'v*'
workflow_dispatch:

jobs:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
id-token: write
steps:
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
with:
submodules: recursive
- uses: foundry-rs/foundry-toolchain@c7450ba673e133f5ee30098b3b54f444d3a2ca2d # v1
with:
version: 1.7.0
- uses: pnpm/action-setup@8912a9102ac27614460f54aedde9e1e7f9aec20d # v6
- uses: actions/setup-node@48b55a011bda9f5d6aeb4c2d9c7362e8dae4041e # v6
with:
node-version-file: .nvmrc
registry-url: https://registry.npmjs.org
cache: pnpm
- run: pnpm install --frozen-lockfile
- name: forge build
working-directory: packages/protokoll
run: forge build
- run: pnpm --filter @protokoll-eth/abi generate
- name: verify abis.ts is up to date with forge artifacts
run: git diff --exit-code packages/abi/src/abis.ts
- run: pnpm --filter @protokoll-eth/abi build
- run: pnpm --filter @protokoll-eth/abi publish --no-git-checks --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ contract Game {

The adapter forwards at most 200 000 gas to the callback, so keep it small.

For TypeScript projects, [`@protokoll-eth/abi`](packages/abi) ships the typed ABIs and the active deployment addresses:

```ts
import { monadVrfAdapterAbi, activeDeployment } from '@protokoll-eth/abi'
```

## How it works

For oracle private key `k` and a 32-byte `roundId`:
Expand Down Expand Up @@ -78,6 +84,7 @@ packages/
test/ Foundry tests (Solidity) + vitest tests (TypeScript)
foundry.toml
docs/ @protokoll/docs - VitePress site (docs.protokoll.dev)
abi/ @protokoll-eth/abi - published ABIs and addresses for integrators
Makefile One-command workflows
pnpm-workspace.yaml Workspace config
```
Expand Down
21 changes: 21 additions & 0 deletions packages/abi/LICENSE
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) 2026 Eric Santana

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
104 changes: 104 additions & 0 deletions packages/abi/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,104 @@
# @protokoll-eth/abi

ABIs and deployment addresses for the [protokoll](https://docs.protokoll.dev) EC-VRF contracts on Monad.

```bash
npm install @protokoll-eth/abi
```

No runtime dependencies. ABIs are exported as `as const` literals so [viem](https://viem.sh) and [wagmi](https://wagmi.sh) infer argument and return types automatically.

## Usage

### Request randomness from a consumer (viem)

```ts
import { createWalletClient, http } from 'viem'
import { privateKeyToAccount } from 'viem/accounts'
import { monadVrfAdapterAbi, activeDeployment } from '@protokoll-eth/abi'

const account = privateKeyToAccount(process.env.PRIVATE_KEY as `0x${string}`)
const client = createWalletClient({
account,
transport: http('https://testnet-rpc.monad.xyz'),
})

const fee = 80_000_000_000_000_000n // 0.08 MON

await client.writeContract({
address: activeDeployment.adapter,
abi: monadVrfAdapterAbi,
functionName: 'requestRandomness',
args: ['0x...32-byte-roundId...'],
value: fee,
chain: undefined,
})
```

### Watch fulfillment events

```ts
import { createPublicClient, http, parseAbiItem } from 'viem'
import { monadVrfAdapterAbi, activeDeployment } from '@protokoll-eth/abi'

const client = createPublicClient({
transport: http('https://testnet-rpc.monad.xyz'),
})

const unwatch = client.watchContractEvent({
address: activeDeployment.adapter,
abi: monadVrfAdapterAbi,
eventName: 'RandomnessFulfilled',
onLogs: (logs) => {
for (const log of logs) {
console.log(log.args.roundId, log.args.beta, log.args.callbackOk)
}
},
})
```

### Implementing the consumer side

`iRandomnessAdapterAbi` is the minimal callback ABI (`fulfillRandomness(bytes32, bytes32)`) that any contract receiving randomness implements. Use it to encode/decode the callback if you need to mock it in tests or call it from off-chain.

## How the ABIs are generated

`src/abis.ts` is generated by [`@wagmi/cli`](https://wagmi.sh/cli) from the forge build artifacts under `packages/protokoll/out/`. To refresh after a contract change:

```bash
cd packages/protokoll && forge build
cd ../abi && pnpm generate
```

The CI publish workflow does both steps automatically before publishing, so the published ABIs always match what was last compiled.

## Exports

| Export | What it is |
|--------------------------|------------------------------------------------------------------------------------------|
| `monadVrfAdapterAbi` | Full ABI of `MonadVRFAdapter` (request/fulfill, views, events, errors). |
| `monadVrfVerifierAbi` | ABI of `MonadVRFVerifier.verifyProof` - useful for off-chain proof checks against RPC. |
| `iRandomnessAdapterAbi` | Consumer-side `fulfillRandomness(bytes32, bytes32)` interface. |
| `monadTestnet` | Chain metadata: `chainId`, `rpc`, `explorer`, `requestFee`, `requestFeeWei` (bigint). |
| `deployments` | Versioned deployment list (newest first). `active: true` marks the live one. |
| `activeDeployment` | Shortcut for the entry with `active: true`. Currently `v0.4.0`. |
| `getDeployment(version)` | Look up a specific historical deployment by version string. |

## Deployments

| Version | Status | Adapter |
|---------|------------|----------------------------------------------|
| v0.4.0 | active | `0xa327402C4eED5862adC123b9b1b93acA475C4668` |
| v0.3.0 | deprecated | `0x9c46878D6736eDC7eAF135DB6B3B2A9Dab2A756F` |
| v0.2.0 | deprecated | `0x7782a54741dd9Dac95a8a79F181EFB97Bac2Dd19` |
| v0.1.x | deprecated | `0xe7f01914d7547d08d155ba47ee9616ee7d504b21` |

See [docs.protokoll.dev/guide/deployments](https://docs.protokoll.dev/guide/deployments) for verifier addresses, deploy transactions, and the rationale behind each version.

## Versioning

This package's version tracks the active contract version. `0.4.0` exports the v0.4.0 contracts as the default. Older deployments stay reachable through `getDeployment('v0.3.0')` etc. so existing integrators can pin to a historical address without forking the package.

## License

MIT
49 changes: 49 additions & 0 deletions packages/abi/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
{
"name": "@protokoll-eth/abi",
"version": "0.4.0",
"description": "ABIs and deployment addresses for the protokoll EC-VRF contracts on Monad",
"license": "MIT",
"homepage": "https://docs.protokoll.dev",
"repository": {
"type": "git",
"url": "git+https://github.com/ericbsantana/protokoll.git",
"directory": "packages/abi"
},
"keywords": [
"protokoll",
"vrf",
"ec-vrf",
"monad",
"abi",
"viem",
"randomness"
],
"type": "module",
"main": "./dist/index.js",
"types": "./dist/index.d.ts",
"exports": {
".": {
"types": "./dist/index.d.ts",
"import": "./dist/index.js"
}
},
"files": [
"dist",
"README.md",
"LICENSE"
],
"scripts": {
"generate": "wagmi generate",
"build": "tsc",
"test": "tsc --noEmit",
"prepublishOnly": "pnpm build"
},
"publishConfig": {
"access": "public",
"provenance": true
},
"devDependencies": {
"@wagmi/cli": "^2.5.0",
"typescript": "^6.0.3"
}
}
Loading
Loading