Skip to content

Commit a744274

Browse files
rickyromboCopilot
andauthored
@audius/eth refactor (#13800)
Normalizes the pattern used for Audius Ethereum contracts clients. - Moves away from viem dep being baked in, and towards a no-deps types package for the ABIs - Makes the package tree-shakeable by removing barrel files and using `"sideEffects": false` - Adds documentation and examples --------- Co-authored-by: Copilot <198982749+Copilot@users.noreply.github.com>
1 parent 8044553 commit a744274

67 files changed

Lines changed: 728 additions & 2982 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.changeset/itchy-pants-unite.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
---
2+
'@audius/eth': major
3+
---
4+
5+
Release 1.0.0
6+
7+
- All contracts now simply export their ABIs and addresses.
8+
- No viem dependency required.
9+
- Treeshakable.
10+
- Added examples and documentation.

package-lock.json

Lines changed: 6 additions & 2017 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

packages/eth/README.md

Lines changed: 112 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,114 @@
11
# `@audius/eth`
22

3-
A Typescript package for interacting with the Audius Governance and Staking [Ethereum Contracts](../../eth-contracts/).
3+
Typed ABIs and production addresses for the [Audius Ethereum contracts](../../eth-contracts/). Designed for use with [viem](https://viem.sh/) and fully tree-shakable — import only the contracts you need.
4+
5+
## Installation
6+
7+
```bash
8+
npm install @audius/eth viem
9+
```
10+
11+
## Usage
12+
13+
Each contract export is a plain object with `abi` and `address`:
14+
15+
```ts
16+
import { createPublicClient, http } from 'viem'
17+
import { mainnet } from 'viem/chains'
18+
import { Staking } from '@audius/eth'
19+
20+
const client = createPublicClient({
21+
chain: mainnet,
22+
transport: http()
23+
})
24+
25+
const totalStaked = await client.readContract({
26+
...Staking,
27+
functionName: 'totalStaked'
28+
})
29+
```
30+
31+
### Check pending rewards claim
32+
33+
```ts
34+
import { ClaimsManager } from '@audius/eth'
35+
36+
const isPending = await client.readContract({
37+
...ClaimsManager,
38+
functionName: 'claimPending',
39+
args: ['0xYourServiceProviderAddress']
40+
})
41+
```
42+
43+
### Read a governance proposal
44+
45+
```ts
46+
import { Governance } from '@audius/eth'
47+
48+
const proposal = await client.readContract({
49+
...Governance,
50+
functionName: 'getProposalById',
51+
args: [1n]
52+
})
53+
```
54+
55+
### Look up service provider endpoints
56+
57+
```ts
58+
import { ServiceProviderFactory, VALIDATOR_SERVICE_TYPE } from '@audius/eth'
59+
60+
// Get the total number of validators
61+
const total = await client.readContract({
62+
...ServiceProviderFactory,
63+
functionName: 'getTotalServiceTypeProviders',
64+
args: [VALIDATOR_SERVICE_TYPE]
65+
})
66+
67+
// Get the endpoint info for the first one
68+
const info = await client.readContract({
69+
...ServiceProviderFactory,
70+
functionName: 'getServiceEndpointInfo',
71+
args: [VALIDATOR_SERVICE_TYPE, 1n]
72+
})
73+
```
74+
75+
### EIP-2612 permit (gasless approval)
76+
77+
`AudiusToken` and `AudiusWormhole` include `domain` and `types` for EIP-712 signing:
78+
79+
```ts
80+
import { AudiusToken } from '@audius/eth'
81+
82+
const signature = await walletClient.signTypedData({
83+
domain: {
84+
...AudiusToken.domain,
85+
chainId: 1,
86+
verifyingContract: AudiusToken.address
87+
},
88+
types: AudiusToken.types,
89+
primaryType: 'Permit',
90+
message: {
91+
owner: '0x...',
92+
spender: '0x...',
93+
value: 1000000000000000000n,
94+
nonce: 0n,
95+
deadline: 99999999999n
96+
}
97+
})
98+
```
99+
100+
## Contracts
101+
102+
| Export | Description |
103+
| ------------------------ | ----------------------------------------------------------------------------------- |
104+
| `AudiusToken` | The AUDIO ERC-20 token. Mintable, pausable, burnable. Supports EIP-2612 `permit()`. |
105+
| `AudiusWormhole` | Sends AUDIO cross-chain via Wormhole with meta-transaction support. |
106+
| `ClaimsManager` | Periodic minting and distribution of AUDIO staking rewards. |
107+
| `DelegateManager` | Delegation of AUDIO tokens to service providers with lockup periods. |
108+
| `EthRewardsManager` | Transfers AUDIO rewards from Ethereum to Solana via Wormhole. |
109+
| `Governance` | On-chain governance: proposals, stake-weighted voting, execution. |
110+
| `Registry` | Central directory mapping contract names to addresses. |
111+
| `ServiceProviderFactory` | Registration and staking for discovery nodes and content nodes. |
112+
| `ServiceTypeManager` | Registry of valid service types and their versions. |
113+
| `Staking` | Core staking contract holding all staked AUDIO with checkpointing. |
114+
| `TrustedNotifierManager` | Registry of trusted notifier entities. |

packages/eth/package.json

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,5 @@
2121
"url": "https://github.com/AudiusProject/apps/issues"
2222
},
2323
"homepage": "https://github.com/AudiusProject/apps/tree/main/packages/eth",
24-
"dependencies": {
25-
"viem": "2.21.21"
26-
}
24+
"sideEffects": false
2725
}
Lines changed: 16 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,18 @@
1-
import type { TypedData } from 'viem'
2-
31
import { abi } from './abi'
42

5-
export type AudiusTokenTypes = typeof AudiusToken.types
6-
export class AudiusToken {
7-
public static readonly abi = abi
8-
9-
public static readonly address =
10-
'0x18aAA7115705e8be94bfFEBDE57Af9BFc265B998' as const
11-
12-
public static readonly types = {
3+
/**
4+
* The AUDIO ERC-20 token contract.
5+
* Initial supply of 1 billion tokens (18 decimals).
6+
* Supports EIP-2612 gasless `permit()` approvals.
7+
*/
8+
export const AudiusToken = {
9+
abi,
10+
address: '0x18aAA7115705e8be94bfFEBDE57Af9BFc265B998' as const,
11+
domain: {
12+
name: 'Audius',
13+
version: '1'
14+
} as const,
15+
types: {
1316
EIP712Domain: [
1417
{ name: 'name', type: 'string' },
1518
{ name: 'version', type: 'string' },
@@ -23,5 +26,7 @@ export class AudiusToken {
2326
{ name: 'nonce', type: 'uint256' },
2427
{ name: 'deadline', type: 'uint256' }
2528
]
26-
} as const satisfies TypedData
29+
} as const
2730
}
31+
32+
export type AudiusTokenTypes = typeof AudiusToken.types

packages/eth/src/audius-token/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,18 @@
1-
import { type TypedData } from 'viem'
2-
31
import { abi } from './abi'
42

5-
export type AudiusWormholeTypes = typeof AudiusWormhole.types
6-
73
/**
84
* Contract that can be permitted to send tokens through the Wormhole Portal
95
* on a user's behalf. Not to be confused with the standard Wormhole contracts,
106
* nor to be confused with wAUDIO (the AudiusToken on Solana).
117
*/
12-
export class AudiusWormhole {
13-
public static readonly abi = abi
14-
15-
public static readonly address = '0x6E7a1F7339bbB62b23D44797b63e4258d283E095'
16-
17-
public static readonly types = {
8+
export const AudiusWormhole = {
9+
abi,
10+
address: '0x6E7a1F7339bbB62b23D44797b63e4258d283E095' as const,
11+
domain: {
12+
name: 'AudiusWormholeClient',
13+
version: '1'
14+
} as const,
15+
types: {
1816
EIP712Domain: [
1917
{ name: 'name', type: 'string' },
2018
{ name: 'version', type: 'string' },
@@ -30,5 +28,7 @@ export class AudiusWormhole {
3028
{ name: 'nonce', type: 'uint32' },
3129
{ name: 'deadline', type: 'uint256' }
3230
]
33-
} as const satisfies TypedData
31+
} as const
3432
}
33+
34+
export type AudiusWormholeTypes = typeof AudiusWormhole.types

packages/eth/src/audius-wormhole/index.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.
Lines changed: 8 additions & 86 deletions
Original file line numberDiff line numberDiff line change
@@ -1,89 +1,11 @@
1-
import type { PublicClient } from 'viem'
2-
31
import { abi } from './abi'
4-
import { CLAIMS_MANAGER_CONTRACT_ADDRESS } from './constants'
5-
6-
export class ClaimsManager {
7-
client: PublicClient
8-
address: `0x${string}`
9-
10-
constructor(
11-
client: PublicClient,
12-
{ address }: { address?: `0x${string}` } = {}
13-
) {
14-
this.client = client
15-
this.address = address ?? CLAIMS_MANAGER_CONTRACT_ADDRESS
16-
}
17-
18-
// Get the duration of a funding round in blocks
19-
getFundingRoundBlockDiff = () =>
20-
this.client.readContract({
21-
address: this.address,
22-
abi,
23-
functionName: 'getFundingRoundBlockDiff'
24-
})
25-
26-
// Get the last block where a funding round was initiated
27-
getLastFundedBlock = () =>
28-
this.client.readContract({
29-
address: this.address,
30-
abi,
31-
functionName: 'getLastFundedBlock'
32-
})
33-
34-
// Get the amount funded per round in wei
35-
getFundsPerRound = () =>
36-
this.client.readContract({
37-
address: this.address,
38-
abi,
39-
functionName: 'getFundsPerRound'
40-
})
41-
42-
// total amount claimed in the current round
43-
getTotalClaimedInRound = () =>
44-
this.client.readContract({
45-
address: this.address,
46-
abi,
47-
functionName: 'getTotalClaimedInRound'
48-
})
49-
50-
// Get the Governance address
51-
getGovernanceAddress = () =>
52-
this.client.readContract({
53-
address: this.address,
54-
abi,
55-
functionName: 'getGovernanceAddress'
56-
})
57-
58-
// Get the ServiceProviderFactory address
59-
getServiceProviderFactoryAddress = () =>
60-
this.client.readContract({
61-
address: this.address,
62-
abi,
63-
functionName: 'getServiceProviderFactoryAddress'
64-
})
65-
66-
// Get the DelegateManager address
67-
getDelegateManagerAddress = () =>
68-
this.client.readContract({
69-
address: this.address,
70-
abi,
71-
functionName: 'getDelegateManagerAddress'
72-
})
73-
74-
// Get the Staking address
75-
getStakingAddress = () =>
76-
this.client.readContract({
77-
address: this.address,
78-
abi,
79-
functionName: 'getStakingAddress'
80-
})
812

82-
claimPending = ({ address }: { address: `0x${string}` }) =>
83-
this.client.readContract({
84-
address: this.address,
85-
abi,
86-
functionName: 'claimPending',
87-
args: [address]
88-
})
3+
/**
4+
* Manages periodic minting and distribution of AUDIO staking rewards.
5+
* Controls funding rounds (~weekly), mints new tokens according to the
6+
* protocol's inflation schedule, and tracks per-round claim amounts.
7+
*/
8+
export const ClaimsManager = {
9+
abi,
10+
address: '0x44617F9dCEd9787C3B06a05B35B4C779a2AA1334' as const
8911
}

packages/eth/src/claims-manager/constants.ts

Lines changed: 0 additions & 2 deletions
This file was deleted.

0 commit comments

Comments
 (0)