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
2 changes: 1 addition & 1 deletion frontend/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -2,4 +2,4 @@
PUBLIC_WALLET_CONNECT_PROJECT_ID=your_project_id_here

# Backend API URL
PUBLIC_API_URL=http://localhost:3001
PUBLIC_API_URL=http://localhost:3001
8 changes: 7 additions & 1 deletion the-guild-smart-contracts/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -10,4 +10,10 @@ CREATE2_SALT=1

# EAS addresses for networks not hardcoded in the deploy script.
# Generic fallback for any other network (used if chain isn't matched)
EAS_ADDRESS=
EAS_ADDRESS=

# AMOY URL
AMOY_RPC_URL=https://polygon-amoy.drpc.org

# ETHERSCAN KEY
ETHERSCAN_API_KEY=
1 change: 1 addition & 0 deletions the-guild-smart-contracts/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ out/
# Ignores development broadcast logs
!/broadcast
/broadcast/*/31337/
/broadcast/*/80002/
/broadcast/**/dry-run/

# Docs
Expand Down
8 changes: 4 additions & 4 deletions the-guild-smart-contracts/INTEGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -38,12 +38,12 @@ export const schemaEncoder = new SchemaEncoder(
);

export function encodeBadgeData(
badgeNameBytes32: `0x${string}`,
justificationBytes32: `0x${string}`
badgeName: `0x${string}`,
justification: `0x${string}`
) {
return schemaEncoder.encodeData([
{ name: 'badgeName', value: badgeNameBytes32, type: 'bytes32' },
{ name: 'justification', value: justificationBytes32, type: 'bytes32' },
{ name: 'badgeName', value: badgeName, type: 'bytes32' },
{ name: 'justification', value: justification, type: 'bytes32' },
]);
}
```
Expand Down
15 changes: 15 additions & 0 deletions the-guild-smart-contracts/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,21 @@ To do this, we can just use EAS' already deployed contracts. First we will regis
### Integration
For detailed frontend integration instructions, see [INTEGRATION.md](./INTEGRATION.md).

## Deployments

### Amoy

Salt: "theguild2"

TheGuildActivityToken
https://amoy.polygonscan.com/address/0x5a79Dd0F66E2C1203948dD49634E506b3D8723A0

TheGuildBadgeRegistry
https://amoy.polygonscan.com/address/0x8baA0d5135D241bd22a9eB35915300aCfB286307

EAS Schema ID:
0x6228d4b9508624b41476a77a09b7582ddc056b92a725f645df6e337be113c9b1

## Foundry Usage

https://book.getfoundry.sh/
Expand Down

Large diffs are not rendered by default.

2 changes: 2 additions & 0 deletions the-guild-smart-contracts/deployAmoy.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
source .env
forge script --chain amoy script/FullDeploymentScript.s.sol:FullDeploymentScript --rpc-url $AMOY_RPC_URL --broadcast --verify -vvvv --interactives 1
8 changes: 7 additions & 1 deletion the-guild-smart-contracts/foundry.toml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ out = "out"
libs = ["lib"]

# Deterministic deployments settings (see: https://getfoundry.sh/guides/deterministic-deployments-using-create2)
solc = "0.8.23"
solc = "0.8.28"
evm_version = "cancun"
bytecode_hash = "none"
cbor_metadata = false
Expand All @@ -16,3 +16,9 @@ remappings = [
]

# See more config options https://github.com/foundry-rs/foundry/blob/master/crates/config/README.md#all-options

[rpc_endpoints]
amoy = "${AMOY_RPC_URL}"

[etherscan]
amoy = { key = "${ETHERSCAN_API_KEY}" }
94 changes: 94 additions & 0 deletions the-guild-smart-contracts/script/FullDeploymentScript.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,94 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.28;

import {Script} from "forge-std/Script.sol";
import {EAS} from "eas-contracts/EAS.sol";
import {AttestationRequestData, AttestationRequest} from "eas-contracts/IEAS.sol";
import {SchemaRegistry} from "eas-contracts/SchemaRegistry.sol";
import {TheGuildActivityToken} from "../src/TheGuildActivityToken.sol";
import {TheGuildBadgeRegistry} from "../src/TheGuildBadgeRegistry.sol";
import {EASUtils} from "./utils/EASUtils.s.sol";
import {console} from "forge-std/console.sol";

contract FullDeploymentScript is Script {
function run() public {
EAS eas;
bytes32 salt = bytes32("theguild2");
// EAS addresses per https://github.com/ethereum-attestation-service/eas-contracts deployments
// Base mainnet (8453) and Base Goerli/Sepolia (84531/84532) use the canonical predeploy 0x...21
// Optimism mainnet (10) and OP Sepolia (11155420) also use canonical 0x...21

eas = EAS(EASUtils.getEASAddress(vm));

vm.startBroadcast();

// Deploy or attach to existing activity token via CREATE2
TheGuildActivityToken activityToken;
try new TheGuildActivityToken{salt: salt}(eas) returns (
TheGuildActivityToken deployed
) {
activityToken = deployed;
} catch {
// If already deployed with same salt + initCode, attach to the predicted address
activityToken = TheGuildActivityToken(
payable(0x5a79Dd0F66E2C1203948dD49634E506b3D8723A0)
);
}

// Register TheGuild Schema
string memory schema = "bytes32 badgeName, bytes32 justification";
SchemaRegistry schemaRegistry = SchemaRegistry(
EASUtils.getSchemaRegistryAddress(vm)
);
bytes32 schemaId = schemaRegistry.register(schema, activityToken, true);
console.logString("Schema ID:");
console.logBytes32(schemaId);

// Deploy or attach to existing badge registry via CREATE2
TheGuildBadgeRegistry badgeRegistry;
try new TheGuildBadgeRegistry{salt: salt}() returns (
TheGuildBadgeRegistry deployed
) {
badgeRegistry = deployed;

// Create some badges
badgeRegistry.createBadge(
bytes32("Rust"),
bytes32("Know how to code in Rust")
);
badgeRegistry.createBadge(
bytes32("Solidity"),
bytes32("Know how to code in Solidity")
);
badgeRegistry.createBadge(
bytes32("TypeScript"),
bytes32("Know how to code in TypeScript")
);
} catch {
// If already deployed with same salt + initCode, attach to the predicted address
badgeRegistry = TheGuildBadgeRegistry(
0x8baA0d5135D241bd22a9eB35915300aCfB286307
);
}

// Create some attestations
AttestationRequestData memory data = AttestationRequestData({
recipient: address(0x1234),
expirationTime: 0,
revocable: true,
refUID: bytes32(0),
data: abi.encode(
bytes32("Rust"),
bytes32("Saw them coding in Rust")
),
value: 0
});

AttestationRequest memory request = AttestationRequest({
schema: schemaId,
data: data
});
eas.attest(request);
vm.stopBroadcast();
}
}
51 changes: 2 additions & 49 deletions the-guild-smart-contracts/script/TheGuildActivityToken.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -4,63 +4,16 @@ pragma solidity ^0.8.13;
import {Script} from "forge-std/Script.sol";
import {IEAS} from "eas-contracts/IEAS.sol";
import {TheGuildActivityToken} from "../src/TheGuildActivityToken.sol";
import {EASUtils} from "./utils/EASUtils.s.sol";

contract TheGuildActivityTokenScript is Script {
function getEASAddress() internal view returns (address) {
// Base and Optimism chains use canonical predeploy
if (
block.chainid == 8453 ||
block.chainid == 84531 ||
block.chainid == 84532 ||
block.chainid == 10 ||
block.chainid == 11155420
) {
return 0x4200000000000000000000000000000000000021;
}
// Arbitrum Sepolia
if (block.chainid == 421614) {
return 0x2521021fc8BF070473E1e1801D3c7B4aB701E1dE;
}
// Polygon Amoy
if (block.chainid == 80002) {
return 0xb101275a60d8bfb14529C421899aD7CA1Ae5B5Fc;
}
// Linea Goerli
if (block.chainid == 59140) {
return 0xaEF4103A04090071165F78D45D83A0C0782c2B2a;
}
//Mainnet
if (block.chainid == 1) {
return 0xA1207F3BBa224E2c9c3c6D5aF63D0eb1582Ce587;
}
//Sepolia
if (block.chainid == 11155111) {
return 0xC2679fBD37d54388Ce493F1DB75320D236e1815e;
}
//Arbitrum One
if (block.chainid == 42161) {
return 0xbD75f629A22Dc1ceD33dDA0b68c546A1c035c458;
}
//Polygon
if (block.chainid == 137) {
return 0x5E634ef5355f45A855d02D66eCD687b1502AF790;
}
// Fallback to env var for other networks
address fallbackAddr = vm.envOr("EAS_ADDRESS", address(0));
require(
fallbackAddr != address(0),
"EAS_ADDRESS not set for this network"
);
return fallbackAddr;
}

function run() public {
address eas;
// EAS addresses per https://github.com/ethereum-attestation-service/eas-contracts deployments
// Base mainnet (8453) and Base Goerli/Sepolia (84531/84532) use the canonical predeploy 0x...21
// Optimism mainnet (10) and OP Sepolia (11155420) also use canonical 0x...21

eas = getEASAddress();
eas = EASUtils.getEASAddress(vm);

vm.startBroadcast();
new TheGuildActivityToken(IEAS(eas));
Expand Down
32 changes: 31 additions & 1 deletion the-guild-smart-contracts/script/TheGuildBadgeRegistry.s.sol
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,37 @@ contract TheGuildBadgeRegistryScript is Script {
bytes32 salt = bytes32(vm.envOr("CREATE2_SALT", uint256(0)));

vm.startBroadcast();
new TheGuildBadgeRegistry{salt: salt}();
TheGuildBadgeRegistry registry = new TheGuildBadgeRegistry{
salt: salt
}();
registry.createBadge(
bytes32("Rust"),
bytes32("Know how to code in Rust")
);
registry.createBadge(
bytes32("Solidity"),
bytes32("Know how to code in Solidity")
);
registry.createBadge(
bytes32("Python"),
bytes32("Know how to code in Python")
);
registry.createBadge(
bytes32("JavaScript"),
bytes32("Know how to code in JavaScript")
);
registry.createBadge(
bytes32("TypeScript"),
bytes32("Know how to code in TypeScript")
);
registry.createBadge(
bytes32("React"),
bytes32("Know how to code in React")
);
registry.createBadge(
bytes32("Next.js"),
bytes32("Know how to code in Next.js")
);
vm.stopBroadcast();
}
}
86 changes: 86 additions & 0 deletions the-guild-smart-contracts/script/utils/EASUtils.s.sol
Original file line number Diff line number Diff line change
@@ -0,0 +1,86 @@
// SPDX-License-Identifier: MIT
pragma solidity ^0.8.13;

import "forge-std/Vm.sol";

library EASUtils {
function getEASAddress(Vm vm) internal view returns (address) {
// Base and Optimism chains use canonical predeploy
if (
block.chainid == 8453 ||
block.chainid == 84531 ||
block.chainid == 84532 ||
block.chainid == 10 ||
block.chainid == 11155420
) {
return 0x4200000000000000000000000000000000000021;
}
// Arbitrum Sepolia
if (block.chainid == 421614) {
return 0x2521021fc8BF070473E1e1801D3c7B4aB701E1dE;
}
// Polygon Amoy
if (block.chainid == 80002) {
return 0xb101275a60d8bfb14529C421899aD7CA1Ae5B5Fc;
}
// Linea Goerli
if (block.chainid == 59140) {
return 0xaEF4103A04090071165F78D45D83A0C0782c2B2a;
}
//Mainnet
if (block.chainid == 1) {
return 0xA1207F3BBa224E2c9c3c6D5aF63D0eb1582Ce587;
}
//Sepolia
if (block.chainid == 11155111) {
return 0xC2679fBD37d54388Ce493F1DB75320D236e1815e;
}
//Arbitrum One
if (block.chainid == 42161) {
return 0xbD75f629A22Dc1ceD33dDA0b68c546A1c035c458;
}
//Polygon
if (block.chainid == 137) {
return 0x5E634ef5355f45A855d02D66eCD687b1502AF790;
}
// Fallback to env var for other networks
address fallbackAddr = vm.envOr("EAS_ADDRESS", address(0));
require(
fallbackAddr != address(0),
"EAS_ADDRESS not set for this network"
);
return fallbackAddr;
}

function getSchemaRegistryAddress(Vm vm) internal view returns (address) {
// Base and Optimism chains use canonical predeploy for SchemaRegistry
if (
block.chainid == 8453 ||
block.chainid == 84531 ||
block.chainid == 84532 ||
block.chainid == 10 ||
block.chainid == 11155420
) {
return 0x4200000000000000000000000000000000000020;
}
// Arbitrum Sepolia
if (block.chainid == 421614) {
return 0x45CB6Fa0870a8Af06796Ac15915619a0f22cd475;
}
// Polygon Amoy
if (block.chainid == 80002) {
return 0x23c5701A1BDa89C61d181BD79E5203c730708AE7;
}
// Linea Goerli
if (block.chainid == 59140) {
return 0x55D26f9ae0203EF95494AE4C170eD35f4Cf77797;
}
// Fallback to env var for other networks
address fallbackAddr = vm.envOr("SCHEMA_REGISTRY_ADDRESS", address(0));
require(
fallbackAddr != address(0),
"SCHEMA_REGISTRY_ADDRESS not set for this network"
);
return fallbackAddr;
}
}
Loading