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
35 changes: 20 additions & 15 deletions .github/workflows/deploy-contracts.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,13 @@ on:
workflow_dispatch:
inputs:
network:
description: 'Network to deploy to (testnet/mainnet)'
description: 'Network to deploy to (arbitrum-sepolia/arbitrum)'
required: true
default: 'testnet'
default: 'arbitrum-sepolia'
type: choice
options:
- testnet
- mainnet
- arbitrum-sepolia
- arbitrum
version:
description: 'Custom version to use (e.g., 1.0.0). Leave empty for auto-increment.'
required: false
Expand Down Expand Up @@ -46,34 +46,39 @@ jobs:
- name: Compile contracts
run: npm run compile

- name: Update local package
run: |
chmod +x scripts/update-package.sh
./scripts/update-package.sh

- name: Generate TypeChain types
run: npm run typechain

- name: Deploy to Testnet
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'testnet')
- name: Deploy to Arbitrum Sepolia
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'arbitrum-sepolia')
run: npm run deploy:arbitrum-testnet
env:
ARBITRUM_SEPOLIA_RPC_URL: ${{ secrets.ARBITRUM_SEPOLIA_RPC_URL }}
PRIVATE_KEY: ${{ secrets.DEPLOYER_PRIVATE_KEY }}
ARBISCAN_API_KEY: ${{ secrets.ARBISCAN_API_KEY }}

- name: Deploy to Mainnet
if: github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'mainnet'
- name: Deploy to Arbitrum
if: github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'arbitrum'
run: npm run deploy:arbitrum
env:
ARBITRUM_ONE_RPC_URL: ${{ secrets.ARBITRUM_ONE_RPC_URL }}
PRIVATE_KEY: ${{ secrets.DEPLOYER_PRIVATE_KEY }}
ARBISCAN_API_KEY: ${{ secrets.ARBISCAN_API_KEY }}

- name: Verify Contracts on Testnet
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'testnet')
- name: Verify Contracts on Arbitrum Sepolia
if: github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'arbitrum-sepolia')
run: npm run verify:all-arbitrum-testnet
env:
ARBITRUM_SEPOLIA_RPC_URL: ${{ secrets.ARBITRUM_SEPOLIA_RPC_URL }}
ARBISCAN_API_KEY: ${{ secrets.ARBISCAN_API_KEY }}

- name: Verify Contracts on Mainnet
if: github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'mainnet'
- name: Verify Contracts on Arbitrum
if: github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'arbitrum'
run: npm run verify:all-arbitrum
env:
ARBITRUM_ONE_RPC_URL: ${{ secrets.ARBITRUM_ONE_RPC_URL }}
Expand All @@ -84,7 +89,7 @@ jobs:
with:
name: deployment-artifacts
path: |
scripts/deployed_addresses_arbitrum.json
scripts/deployed_addresses.json
typechain-types/
if-no-files-found: error

Expand Down Expand Up @@ -140,7 +145,7 @@ jobs:
git push origin HEAD

- name: Generate Package
run: npx ts-node scripts/generate-package.ts
run: npx ts-node scripts/generate-package.ts ${{ github.event_name == 'push' && 'arbitrum-sepolia' || github.event.inputs.network }}

- name: Publish Package
run: |
Expand All @@ -157,7 +162,7 @@ jobs:
# name: Contracts v${{ env.NEW_VERSION }}
# body: |
# DeCleanup Network Smart Contracts Release
# - Deployed to ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'mainnet' && 'Arbitrum Mainnet' || 'Arbitrum Testnet' }}
# - Deployed to ${{ github.event_name == 'workflow_dispatch' && github.event.inputs.network == 'arbitrum' && 'Arbitrum' || 'Arbitrum Sepolia' }}
# - Published to npm as @decleanup/contracts@${{ env.NEW_VERSION }}
# env:
# GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
92 changes: 48 additions & 44 deletions docs/CONTRACT_PACKAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,59 +14,73 @@ npm install @decleanup/contracts

```typescript
import { ethers } from 'ethers';
import { DCUToken, RewardLogic, DCUAccounting, DCUStorage, DCURewardManager, DipNft } from '@decleanup/contracts';
import { DCUContracts, Networks } from '@decleanup/contracts';

// Initialize with a specific network
const contracts = new DCUContracts(Networks.ARBITRUM_SEPOLIA);

// Initialize provider and signer
const provider = new ethers.JsonRpcProvider('YOUR_RPC_URL');
const signer = new ethers.Wallet('YOUR_PRIVATE_KEY', provider);

// Get contract instances with full type inference
const token = DCUToken.contract.connect(signer);
const rewardLogic = RewardLogic.contract.connect(signer);
const accounting = DCUAccounting.contract.connect(signer);
const storage = DCUStorage.contract.connect(signer);
const rewardManager = DCURewardManager.contract.connect(signer);
const dipNft = DipNft.contract.connect(signer);
const token = contracts.DCUToken.connect(signer);
const rewardLogic = contracts.RewardLogic.connect(signer);
const accounting = contracts.DCUAccounting.connect(signer);
const storage = contracts.DCUStorage.connect(signer);
const rewardManager = contracts.DCURewardManager.connect(signer);
const dipNft = contracts.DipNft.connect(signer);
```

### Contract Information

Each contract export contains the following information:
Each contract provides the following information:

```typescript
import { DCUToken } from '@decleanup/contracts';
import { DCUContracts, Networks } from '@decleanup/contracts';

const contracts = new DCUContracts(Networks.ARBITRUM_SEPOLIA);

// Contract address
console.log(DCUToken.address);
console.log(contracts.DCUToken.address);

// Contract ABI
console.log(DCUToken.abi);
console.log(contracts.DCUToken.abi);

// Network information
console.log(DCUToken.network); // 'arbitrum' or 'arbitrum-testnet'
console.log(DCUToken.chainId); // Chain ID
console.log(contracts.DCUToken.network); // 'arbitrum-sepolia' or 'arbitrum'
console.log(contracts.DCUToken.chainId); // Chain ID

// Type-safe contract instance
const token = DCUToken.contract.connect(signer);
const token = contracts.DCUToken.connect(signer);
```

### Network Information
### Network Support

The package supports multiple networks through the `Networks` enum:

```typescript
import { network } from '@decleanup/contracts';
import { DCUContracts, Networks } from '@decleanup/contracts';

console.log(network.name); // Network name
console.log(network.chainId); // Chain ID
console.log(network.deployedAt); // Deployment timestamp
// Initialize for Arbitrum Sepolia
const sepoliaContracts = new DCUContracts(Networks.ARBITRUM_SEPOLIA);

// Initialize for Arbitrum Mainnet
const mainnetContracts = new DCUContracts(Networks.ARBITRUM);

// Check network information
console.log(sepoliaContracts.DCUToken.chainId); // 421614
console.log(mainnetContracts.DCUToken.chainId); // 42161
```

### Example: Token Operations

```typescript
import { DCUToken } from '@decleanup/contracts';
import { DCUContracts, Networks } from '@decleanup/contracts';

async function transferTokens(signer: ethers.Signer, recipient: string, amount: bigint) {
const token = DCUToken.contract.connect(signer);
const contracts = new DCUContracts(Networks.ARBITRUM_SEPOLIA);
const token = contracts.DCUToken.connect(signer);

// Type-safe transfer
const tx = await token.transfer(recipient, amount);
Expand All @@ -81,11 +95,12 @@ async function transferTokens(signer: ethers.Signer, recipient: string, amount:
### Example: Reward Operations

```typescript
import { RewardLogic, DCURewardManager } from '@decleanup/contracts';
import { DCUContracts, Networks } from '@decleanup/contracts';

async function claimRewards(signer: ethers.Signer, submissionId: bigint) {
const rewardManager = DCURewardManager.contract.connect(signer);
const rewardLogic = RewardLogic.contract.connect(signer);
const contracts = new DCUContracts(Networks.ARBITRUM_SEPOLIA);
const rewardManager = contracts.DCURewardManager.connect(signer);
const rewardLogic = contracts.RewardLogic.connect(signer);

// Check if rewards are available
const isAvailable = await rewardLogic.isRewardAvailable(submissionId);
Expand All @@ -102,10 +117,11 @@ async function claimRewards(signer: ethers.Signer, submissionId: bigint) {
### Example: NFT Operations

```typescript
import { DipNft } from '@decleanup/contracts';
import { DCUContracts, Networks } from '@decleanup/contracts';

async function mintNFT(signer: ethers.Signer, to: string, tokenURI: string) {
const nft = DipNft.contract.connect(signer);
const contracts = new DCUContracts(Networks.ARBITRUM_SEPOLIA);
const nft = contracts.DipNft.connect(signer);

// Mint new NFT
const tx = await nft.mint(to, tokenURI);
Expand All @@ -130,39 +146,27 @@ The package includes TypeChain-generated type definitions, providing:
- Compile-time error checking

```typescript
import { DCUToken } from '@decleanup/contracts';
import { DCUContracts, Networks } from '@decleanup/contracts';

const token = DCUToken.contract.connect(signer);
const contracts = new DCUContracts(Networks.ARBITRUM_SEPOLIA);
const token = contracts.DCUToken.connect(signer);

// Type-safe method calls
await token.transfer(recipient, amount); // ✅ Correct
await token.transfer(recipient, "100"); // ❌ Error: amount must be bigint
```

## Network Support

The package supports both Arbitrum mainnet and testnet deployments. The correct contract addresses and ABIs are automatically selected based on the network you're connecting to.

```typescript
import { network } from '@co/contracts';

if (network.chainId === 42161) {
console.log('Connected to Arbitrum mainnet');
} else if (network.chainId === 421614) {
console.log('Connected to Arbitrum testnet');
}
```

## Error Handling

All contract interactions include proper error handling:

```typescript
import { DCUToken } from '@decleanup/contracts';
import { DCUContracts, Networks } from '@decleanup/contracts';

async function safeTransfer(signer: ethers.Signer, recipient: string, amount: bigint) {
try {
const token = DCUToken.contract.connect(signer);
const contracts = new DCUContracts(Networks.ARBITRUM_SEPOLIA);
const token = contracts.DCUToken.connect(signer);
const tx = await token.transfer(recipient, amount);
await tx.wait();
return true;
Expand Down
Loading