Skip to content

Commit

Permalink
feat: add service provider address to config (#93)
Browse files Browse the repository at this point in the history
  • Loading branch information
jahabeebs authored Nov 22, 2024
1 parent 811bb8b commit 09c4dcd
Show file tree
Hide file tree
Showing 12 changed files with 210 additions and 55 deletions.
2 changes: 1 addition & 1 deletion apps/agent/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,4 @@ BLOCK_NUMBER_BLOCKMETA_TOKEN=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNlIjoidH
EBO_AGENT_CONFIG_FILE_PATH="./config.example.yml"

# Discord webhook notifications
DISCORD_WEBHOOK=YOUR_DISCORD_WEBHOOK
DISCORD_WEBHOOK=YOUR_DISCORD_WEBHOOK
2 changes: 2 additions & 0 deletions apps/agent/config.example.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,8 @@ protocolProvider:
eboRequestCreator: "0x1234567890123456789012345678901234567890" # EBO Request Creator contract
bondEscalationModule: "0x1234567890123456789012345678901234567890" # Bond Escalation Module contract
horizonAccountingExtension: "0x1234567890123456789012345678901234567890" # Accounting extension contract
accessControl:
serviceProviderAddress: "0x1234567890123456789012345678901234567890" # Service Provider Address

blockNumberService:
blockmetaConfig:
Expand Down
11 changes: 11 additions & 0 deletions apps/agent/src/config/schemas.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@ export const envSchema = z.object({
});

const addressSchema = z.string().refine((address) => isAddress(address));

const rpcConfigSchema = z.object({
chainId: z
.string()
Expand All @@ -43,6 +44,15 @@ const rpcConfigSchema = z.object({
retryInterval: z.number().int().positive(),
});

export const accessControlSchema = z.object({
serviceProviderAddress: z
.string()
.refine((val) => isAddress(val), {
message: "serviceProviderAddress must be a valid blockchain address",
})
.optional(),
});

const protocolProviderConfigSchema = z.object({
rpcsConfig: z.object({
l1: rpcConfigSchema,
Expand All @@ -55,6 +65,7 @@ const protocolProviderConfigSchema = z.object({
bondEscalationModule: addressSchema,
horizonAccountingExtension: addressSchema,
}),
accessControl: accessControlSchema.optional(),
});

const blockNumberServiceSchema = z.object({
Expand Down
1 change: 1 addition & 0 deletions apps/agent/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const main = async (): Promise<void> => {
config.protocolProvider.rpcsConfig,
config.protocolProvider.contracts,
config.protocolProvider.privateKey,
config.protocolProvider.accessControl?.serviceProviderAddress,
logger,
blockNumberService,
);
Expand Down
16 changes: 14 additions & 2 deletions apps/scripts/utilities/approveAccountingModules.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { ProtocolProvider } from "@ebo-agent/automated-dispute/src/index.js";
import { mockLogger } from "@ebo-agent/automated-dispute/tests/mocks/logger.mocks.js";
import { Caip2ChainId } from "@ebo-agent/shared";
import * as dotenv from "dotenv";
import { Address, Hex, isHex } from "viem";
import { Address, Hex, isAddress, isHex } from "viem";
import { z } from "zod";

dotenv.config();
Expand Down Expand Up @@ -70,6 +70,12 @@ const envSchema = z.object({
CONTRACTS_ADDRESSES: stringToJSONSchema.pipe(contractsAddressesSchema),
BONDED_RESPONSE_MODULE_ADDRESS: z.string().min(1, "BONDED_RESPONSE_MODULE_ADDRESS is required"),
BOND_ESCALATION_MODULE_ADDRESS: z.string().min(1, "BOND_ESCALATION_MODULE_ADDRESS is required"),
SERVICE_PROVIDER_ADDRESS: z
.string()
.refine((val) => isAddress(val), {
message: "SERVICE_PROVIDER_ADDRESS must be a valid blockchain address",
})
.optional(),
});

const envResult = envSchema.safeParse(process.env);
Expand Down Expand Up @@ -103,7 +109,13 @@ const rpcConfig = {

const contracts = env.CONTRACTS_ADDRESSES;

const provider = new ProtocolProvider(rpcConfig, contracts, env.PRIVATE_KEY as Hex, mockLogger());
const provider = new ProtocolProvider(
rpcConfig,
contracts,
env.PRIVATE_KEY as Hex,
env.SERVICE_PROVIDER_ADDRESS,
mockLogger(),
);

/**
* Approves the necessary modules by calling approveModule on ProtocolProvider.
Expand Down
4 changes: 4 additions & 0 deletions packages/automated-dispute/src/config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,4 +4,8 @@ const ConfigSchema = z.object({
DISCORD_WEBHOOK: z.string().url().optional(),
});

/**
* Parses and validates the environment variables using the defined schema.
* If validation fails, it throws an error detailing the issues.
*/
export const config = ConfigSchema.parse(process.env);
28 changes: 24 additions & 4 deletions packages/automated-dispute/src/providers/protocolProvider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,22 @@ type ProtocolRpcConfig = {
l2: RpcConfig;
};

type ProtocolProviderConfig = ProtocolRpcConfig & {
serviceProviderAddress?: Address;
};

// TODO: add default caching strategy for RPC client

export class ProtocolProvider implements IProtocolProvider {
private l1ReadClient: PublicClient<FallbackTransport<HttpTransport[]>>;
private l2ReadClient: PublicClient<FallbackTransport<HttpTransport[]>>;
private l2WriteClient: WalletClient<FallbackTransport<HttpTransport[]>, Chain, Account>;
private readonly l2ReadClient: PublicClient<FallbackTransport<HttpTransport[]>>;
private readonly l2WriteClient: WalletClient<
FallbackTransport<HttpTransport[]>,
Chain,
Account
>;
private readonly blockNumberService?: BlockNumberService;
private readonly serviceProviderAddress: Address;

private oracleContract: GetContractReturnType<
typeof oracleAbi,
Expand Down Expand Up @@ -113,16 +122,18 @@ export class ProtocolProvider implements IProtocolProvider {

/**
* Creates a new ProtocolProvider instance
* @param rpcConfig The configuration for RPC connections including URLs, timeout, retry interval, and transaction receipt confirmations
* @param rpcConfig The configuration for the serviceProviderAddress and RPC connections, including URLs, timeout, retry interval, and transaction receipt confirmations
* @param contracts The addresses of the protocol contracts that will be instantiated
* @param privateKey The private key of the account that will be used to interact with the contracts
* @param serviceProviderAddress The address of the service provider
* @param logger The logger instance
* @param blockNumberService The service that will be used to fetch block numbers
*/
constructor(
private readonly rpcConfig: ProtocolRpcConfig,
private readonly rpcConfig: ProtocolProviderConfig,
contracts: ProtocolContractsAddresses,
privateKey: Hex,
serviceProviderAddress: Address | undefined,
private readonly logger: ILogger,
blockNumberService?: BlockNumberService,
) {
Expand All @@ -133,6 +144,8 @@ export class ProtocolProvider implements IProtocolProvider {
this.l2ReadClient = this.createReadClient(rpcConfig.l2, l2Chain);
this.l2WriteClient = this.createWriteClient(rpcConfig.l2, l2Chain, privateKey);
this.blockNumberService = blockNumberService;
this.serviceProviderAddress =
serviceProviderAddress || privateKeyToAccount(privateKey).address;

// Instantiate all the protocol contracts
this.oracleContract = getContract({
Expand Down Expand Up @@ -197,6 +210,13 @@ export class ProtocolProvider implements IProtocolProvider {
getEscalation: this.getEscalation.bind(this),
};

/**
* @returns {Address} The address of the service provider.
*/
public getServiceProviderAddress(): Address {
return this.serviceProviderAddress;
}

private createReadClient(
config: RpcConfig,
chain: Chain,
Expand Down
2 changes: 2 additions & 0 deletions packages/automated-dispute/tests/mocks/eboActor.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
DEFAULT_MOCKED_PROTOCOL_CONTRACTS,
DEFAULT_MOCKED_REQUEST_CREATED_DATA,
mockedPrivateKey,
mockServiceProviderAddress,
} from "../services/eboActor/fixtures.js";

/**
Expand Down Expand Up @@ -50,6 +51,7 @@ export function buildEboActor(request: Request, logger: ILogger) {
},
DEFAULT_MOCKED_PROTOCOL_CONTRACTS,
mockedPrivateKey,
mockServiceProviderAddress,
logger,
);

Expand Down
4 changes: 3 additions & 1 deletion packages/automated-dispute/tests/mocks/eboProcessor.mocks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@ import { AccountingModules } from "../../src/types/prophet.js";
import {
DEFAULT_MOCKED_PROTOCOL_CONTRACTS,
mockedPrivateKey,
mockServiceProviderAddress,
} from "../services/eboActor/fixtures.js";

export function buildEboProcessor(
Expand All @@ -16,7 +17,7 @@ export function buildEboProcessor(
responseModule: "0x02",
escalationModule: "0x03",
},
notifier?: NotificationService,
notifier: NotificationService,
) {
const blockNumberRpcUrls = new Map<Caip2ChainId, string[]>([
["eip155:1" as Caip2ChainId, ["http://localhost:8539"]],
Expand Down Expand Up @@ -56,6 +57,7 @@ export function buildEboProcessor(
},
DEFAULT_MOCKED_PROTOCOL_CONTRACTS,
mockedPrivateKey,
mockServiceProviderAddress,
logger,
blockNumberService,
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ import {
export const mockedPrivateKey =
"0xac0974bec39a17e36ba4a6b4d238ff944bacb478cbed5efcae784d7bf4f2ff80";

export const mockServiceProviderAddress = "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" as Address;

export const DEFAULT_MOCKED_PROTOCOL_CONTRACTS: ProtocolContractsAddresses = {
oracle: "0x1234560000000000000000000000000000000000" as Address,
epochManager: "0x6543210000000000000000000000000000000000" as Address,
Expand Down
Loading

0 comments on commit 09c4dcd

Please sign in to comment.