diff --git a/.gitignore b/.gitignore index 8301e83..93d68b6 100644 --- a/.gitignore +++ b/.gitignore @@ -22,4 +22,5 @@ node_modules # cli dist .vercel +*.zip *.gz diff --git a/donations/build/DonationContract/DonationContract.wasm b/donations/build/DonationContract/DonationContract.wasm new file mode 100644 index 0000000..a7c9181 Binary files /dev/null and b/donations/build/DonationContract/DonationContract.wasm differ diff --git a/donations/build/DonationContract/abis/DonationContract.json b/donations/build/DonationContract/abis/DonationContract.json new file mode 100644 index 0000000..1154ea7 --- /dev/null +++ b/donations/build/DonationContract/abis/DonationContract.json @@ -0,0 +1,350 @@ +[ + { + "inputs": [ + { + "internalType": "address", + "name": "_batchSwapContract", + "type": "address" + }, + { + "internalType": "address", + "name": "_swapRouter", + "type": "address" + } + ], + "stateMutability": "nonpayable", + "type": "constructor" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "campaignId", + "type": "uint256" + } + ], + "name": "CampaignClosed", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "campaignId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "campaignOwner", + "type": "address" + }, + { + "indexed": false, + "internalType": "string", + "name": "campaignName", + "type": "string" + } + ], + "name": "CampaignCreated", + "type": "event" + }, + { + "anonymous": false, + "inputs": [ + { + "indexed": false, + "internalType": "uint256", + "name": "campaignId", + "type": "uint256" + }, + { + "indexed": false, + "internalType": "address", + "name": "donor", + "type": "address" + }, + { + "indexed": false, + "internalType": "address[]", + "name": "tokenAddresses", + "type": "address[]" + }, + { + "indexed": false, + "internalType": "uint256[]", + "name": "tokenAmounts", + "type": "uint256[]" + } + ], + "name": "DonationReceived", + "type": "event" + }, + { + "inputs": [], + "name": "MAX_PRICE_LIMIT", + "outputs": [ + { + "internalType": "uint160", + "name": "", + "type": "uint160" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "MIN_PRICE_LIMIT", + "outputs": [ + { + "internalType": "uint160", + "name": "", + "type": "uint160" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "batchSwapRouter", + "outputs": [ + { + "internalType": "contract PoolBatchSwapTest", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "name": "campaigns", + "outputs": [ + { + "internalType": "address", + "name": "campaignOwner", + "type": "address" + }, + { + "internalType": "bool", + "name": "isLive", + "type": "bool" + }, + { + "internalType": "string", + "name": "campaignName", + "type": "string" + }, + { + "internalType": "uint256", + "name": "goalAmount", + "type": "uint256" + }, + { + "internalType": "address", + "name": "goalToken", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "uint256", + "name": "_campaignId", + "type": "uint256" + } + ], + "name": "closeCampaign", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "string", + "name": "_campaignName", + "type": "string" + }, + { + "internalType": "address", + "name": "goalToken", + "type": "address" + }, + { + "internalType": "uint256", + "name": "goalAmount", + "type": "uint256" + } + ], + "name": "createCampaign", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "internalType": "address[]", + "name": "_tokenAddresses", + "type": "address[]" + }, + { + "internalType": "uint256[]", + "name": "_tokenAmounts", + "type": "uint256[]" + }, + { + "internalType": "uint256", + "name": "_campaignId", + "type": "uint256" + } + ], + "name": "donate", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "Currency", + "name": "currency0", + "type": "address" + }, + { + "internalType": "Currency", + "name": "currency1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "internalType": "contract IHooks", + "name": "hooks", + "type": "address" + } + ], + "internalType": "struct PoolKey[]", + "name": "keys", + "type": "tuple[]" + }, + { + "internalType": "int256[]", + "name": "amountsSpecified", + "type": "int256[]" + }, + { + "internalType": "bool[]", + "name": "zeroForOnes", + "type": "bool[]" + } + ], + "name": "makeBatchSwap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [ + { + "components": [ + { + "internalType": "Currency", + "name": "currency0", + "type": "address" + }, + { + "internalType": "Currency", + "name": "currency1", + "type": "address" + }, + { + "internalType": "uint24", + "name": "fee", + "type": "uint24" + }, + { + "internalType": "int24", + "name": "tickSpacing", + "type": "int24" + }, + { + "internalType": "contract IHooks", + "name": "hooks", + "type": "address" + } + ], + "internalType": "struct PoolKey", + "name": "key", + "type": "tuple" + }, + { + "internalType": "int256", + "name": "amountSpecified", + "type": "int256" + }, + { + "internalType": "bool", + "name": "zeroForOne", + "type": "bool" + } + ], + "name": "makeSwap", + "outputs": [], + "stateMutability": "nonpayable", + "type": "function" + }, + { + "inputs": [], + "name": "nextCampaignId", + "outputs": [ + { + "internalType": "uint256", + "name": "", + "type": "uint256" + } + ], + "stateMutability": "view", + "type": "function" + }, + { + "inputs": [], + "name": "swapRouter", + "outputs": [ + { + "internalType": "contract PoolSwapTest", + "name": "", + "type": "address" + } + ], + "stateMutability": "view", + "type": "function" + } +] \ No newline at end of file diff --git a/donations/build/schema.graphql b/donations/build/schema.graphql new file mode 100644 index 0000000..1defba6 --- /dev/null +++ b/donations/build/schema.graphql @@ -0,0 +1,28 @@ +type CampaignClosed @entity(immutable: true) { + id: Bytes! + campaignId: BigInt! # uint256 + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type CampaignCreated @entity(immutable: true) { + id: Bytes! + campaignId: BigInt! # uint256 + campaignOwner: Bytes! # address + campaignName: String! # string + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} + +type DonationReceived @entity(immutable: true) { + id: Bytes! + campaignId: BigInt! # uint256 + donor: Bytes! # address + # tokenAddresses: [Bytes!]! # address[] + tokenAmounts: [BigInt!]! # uint256[] + blockNumber: BigInt! + blockTimestamp: BigInt! + transactionHash: Bytes! +} diff --git a/donations/build/subgraph.yaml b/donations/build/subgraph.yaml new file mode 100644 index 0000000..15660a0 --- /dev/null +++ b/donations/build/subgraph.yaml @@ -0,0 +1,32 @@ +specVersion: 1.0.0 +indexerHints: + prune: auto +schema: + file: schema.graphql +dataSources: + - kind: ethereum + name: DonationContract + network: sepolia + source: + address: "0x015c05c99467aca9eb8313bFe836c75067C01ce8" + abi: DonationContract + startBlock: 6019786 + mapping: + kind: ethereum/events + apiVersion: 0.0.7 + language: wasm/assemblyscript + entities: + - CampaignClosed + - CampaignCreated + - DonationReceived + abis: + - name: DonationContract + file: DonationContract\abis\DonationContract.json + eventHandlers: + - event: CampaignClosed(uint256) + handler: handleCampaignClosed + - event: CampaignCreated(uint256,address,string) + handler: handleCampaignCreated + - event: DonationReceived(uint256,address,address[],uint256[]) + handler: handleDonationReceived + file: DonationContract\DonationContract.wasm diff --git a/donations/generated/DonationContract/DonationContract.ts b/donations/generated/DonationContract/DonationContract.ts new file mode 100644 index 0000000..efc04d9 --- /dev/null +++ b/donations/generated/DonationContract/DonationContract.ts @@ -0,0 +1,547 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + +import { + ethereum, + JSONValue, + TypedMap, + Entity, + Bytes, + Address, + BigInt, +} from "@graphprotocol/graph-ts"; + +export class CampaignClosed extends ethereum.Event { + get params(): CampaignClosed__Params { + return new CampaignClosed__Params(this); + } +} + +export class CampaignClosed__Params { + _event: CampaignClosed; + + constructor(event: CampaignClosed) { + this._event = event; + } + + get campaignId(): BigInt { + return this._event.parameters[0].value.toBigInt(); + } +} + +export class CampaignCreated extends ethereum.Event { + get params(): CampaignCreated__Params { + return new CampaignCreated__Params(this); + } +} + +export class CampaignCreated__Params { + _event: CampaignCreated; + + constructor(event: CampaignCreated) { + this._event = event; + } + + get campaignId(): BigInt { + return this._event.parameters[0].value.toBigInt(); + } + + get campaignOwner(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get campaignName(): string { + return this._event.parameters[2].value.toString(); + } +} + +export class DonationReceived extends ethereum.Event { + get params(): DonationReceived__Params { + return new DonationReceived__Params(this); + } +} + +export class DonationReceived__Params { + _event: DonationReceived; + + constructor(event: DonationReceived) { + this._event = event; + } + + get campaignId(): BigInt { + return this._event.parameters[0].value.toBigInt(); + } + + get donor(): Address { + return this._event.parameters[1].value.toAddress(); + } + + get tokenAddresses(): Array
{ + return this._event.parameters[2].value.toAddressArray(); + } + + get tokenAmounts(): Array { + return this._event.parameters[3].value.toBigIntArray(); + } +} + +export class DonationContract__campaignsResult { + value0: Address; + value1: boolean; + value2: string; + value3: BigInt; + value4: Address; + + constructor( + value0: Address, + value1: boolean, + value2: string, + value3: BigInt, + value4: Address, + ) { + this.value0 = value0; + this.value1 = value1; + this.value2 = value2; + this.value3 = value3; + this.value4 = value4; + } + + toMap(): TypedMap { + let map = new TypedMap(); + map.set("value0", ethereum.Value.fromAddress(this.value0)); + map.set("value1", ethereum.Value.fromBoolean(this.value1)); + map.set("value2", ethereum.Value.fromString(this.value2)); + map.set("value3", ethereum.Value.fromUnsignedBigInt(this.value3)); + map.set("value4", ethereum.Value.fromAddress(this.value4)); + return map; + } + + getCampaignOwner(): Address { + return this.value0; + } + + getIsLive(): boolean { + return this.value1; + } + + getCampaignName(): string { + return this.value2; + } + + getGoalAmount(): BigInt { + return this.value3; + } + + getGoalToken(): Address { + return this.value4; + } +} + +export class DonationContract extends ethereum.SmartContract { + static bind(address: Address): DonationContract { + return new DonationContract("DonationContract", address); + } + + MAX_PRICE_LIMIT(): BigInt { + let result = super.call( + "MAX_PRICE_LIMIT", + "MAX_PRICE_LIMIT():(uint160)", + [], + ); + + return result[0].toBigInt(); + } + + try_MAX_PRICE_LIMIT(): ethereum.CallResult { + let result = super.tryCall( + "MAX_PRICE_LIMIT", + "MAX_PRICE_LIMIT():(uint160)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + MIN_PRICE_LIMIT(): BigInt { + let result = super.call( + "MIN_PRICE_LIMIT", + "MIN_PRICE_LIMIT():(uint160)", + [], + ); + + return result[0].toBigInt(); + } + + try_MIN_PRICE_LIMIT(): ethereum.CallResult { + let result = super.tryCall( + "MIN_PRICE_LIMIT", + "MIN_PRICE_LIMIT():(uint160)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + batchSwapRouter(): Address { + let result = super.call( + "batchSwapRouter", + "batchSwapRouter():(address)", + [], + ); + + return result[0].toAddress(); + } + + try_batchSwapRouter(): ethereum.CallResult
{ + let result = super.tryCall( + "batchSwapRouter", + "batchSwapRouter():(address)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toAddress()); + } + + campaigns(param0: BigInt): DonationContract__campaignsResult { + let result = super.call( + "campaigns", + "campaigns(uint256):(address,bool,string,uint256,address)", + [ethereum.Value.fromUnsignedBigInt(param0)], + ); + + return new DonationContract__campaignsResult( + result[0].toAddress(), + result[1].toBoolean(), + result[2].toString(), + result[3].toBigInt(), + result[4].toAddress(), + ); + } + + try_campaigns( + param0: BigInt, + ): ethereum.CallResult { + let result = super.tryCall( + "campaigns", + "campaigns(uint256):(address,bool,string,uint256,address)", + [ethereum.Value.fromUnsignedBigInt(param0)], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue( + new DonationContract__campaignsResult( + value[0].toAddress(), + value[1].toBoolean(), + value[2].toString(), + value[3].toBigInt(), + value[4].toAddress(), + ), + ); + } + + nextCampaignId(): BigInt { + let result = super.call("nextCampaignId", "nextCampaignId():(uint256)", []); + + return result[0].toBigInt(); + } + + try_nextCampaignId(): ethereum.CallResult { + let result = super.tryCall( + "nextCampaignId", + "nextCampaignId():(uint256)", + [], + ); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toBigInt()); + } + + swapRouter(): Address { + let result = super.call("swapRouter", "swapRouter():(address)", []); + + return result[0].toAddress(); + } + + try_swapRouter(): ethereum.CallResult
{ + let result = super.tryCall("swapRouter", "swapRouter():(address)", []); + if (result.reverted) { + return new ethereum.CallResult(); + } + let value = result.value; + return ethereum.CallResult.fromValue(value[0].toAddress()); + } +} + +export class ConstructorCall extends ethereum.Call { + get inputs(): ConstructorCall__Inputs { + return new ConstructorCall__Inputs(this); + } + + get outputs(): ConstructorCall__Outputs { + return new ConstructorCall__Outputs(this); + } +} + +export class ConstructorCall__Inputs { + _call: ConstructorCall; + + constructor(call: ConstructorCall) { + this._call = call; + } + + get _batchSwapContract(): Address { + return this._call.inputValues[0].value.toAddress(); + } + + get _swapRouter(): Address { + return this._call.inputValues[1].value.toAddress(); + } +} + +export class ConstructorCall__Outputs { + _call: ConstructorCall; + + constructor(call: ConstructorCall) { + this._call = call; + } +} + +export class CloseCampaignCall extends ethereum.Call { + get inputs(): CloseCampaignCall__Inputs { + return new CloseCampaignCall__Inputs(this); + } + + get outputs(): CloseCampaignCall__Outputs { + return new CloseCampaignCall__Outputs(this); + } +} + +export class CloseCampaignCall__Inputs { + _call: CloseCampaignCall; + + constructor(call: CloseCampaignCall) { + this._call = call; + } + + get _campaignId(): BigInt { + return this._call.inputValues[0].value.toBigInt(); + } +} + +export class CloseCampaignCall__Outputs { + _call: CloseCampaignCall; + + constructor(call: CloseCampaignCall) { + this._call = call; + } +} + +export class CreateCampaignCall extends ethereum.Call { + get inputs(): CreateCampaignCall__Inputs { + return new CreateCampaignCall__Inputs(this); + } + + get outputs(): CreateCampaignCall__Outputs { + return new CreateCampaignCall__Outputs(this); + } +} + +export class CreateCampaignCall__Inputs { + _call: CreateCampaignCall; + + constructor(call: CreateCampaignCall) { + this._call = call; + } + + get _campaignName(): string { + return this._call.inputValues[0].value.toString(); + } + + get goalToken(): Address { + return this._call.inputValues[1].value.toAddress(); + } + + get goalAmount(): BigInt { + return this._call.inputValues[2].value.toBigInt(); + } +} + +export class CreateCampaignCall__Outputs { + _call: CreateCampaignCall; + + constructor(call: CreateCampaignCall) { + this._call = call; + } +} + +export class DonateCall extends ethereum.Call { + get inputs(): DonateCall__Inputs { + return new DonateCall__Inputs(this); + } + + get outputs(): DonateCall__Outputs { + return new DonateCall__Outputs(this); + } +} + +export class DonateCall__Inputs { + _call: DonateCall; + + constructor(call: DonateCall) { + this._call = call; + } + + get _tokenAddresses(): Array
{ + return this._call.inputValues[0].value.toAddressArray(); + } + + get _tokenAmounts(): Array { + return this._call.inputValues[1].value.toBigIntArray(); + } + + get _campaignId(): BigInt { + return this._call.inputValues[2].value.toBigInt(); + } +} + +export class DonateCall__Outputs { + _call: DonateCall; + + constructor(call: DonateCall) { + this._call = call; + } +} + +export class MakeBatchSwapCall extends ethereum.Call { + get inputs(): MakeBatchSwapCall__Inputs { + return new MakeBatchSwapCall__Inputs(this); + } + + get outputs(): MakeBatchSwapCall__Outputs { + return new MakeBatchSwapCall__Outputs(this); + } +} + +export class MakeBatchSwapCall__Inputs { + _call: MakeBatchSwapCall; + + constructor(call: MakeBatchSwapCall) { + this._call = call; + } + + get keys(): Array { + return this._call.inputValues[0].value.toTupleArray(); + } + + get amountsSpecified(): Array { + return this._call.inputValues[1].value.toBigIntArray(); + } + + get zeroForOnes(): Array { + return this._call.inputValues[2].value.toBooleanArray(); + } +} + +export class MakeBatchSwapCall__Outputs { + _call: MakeBatchSwapCall; + + constructor(call: MakeBatchSwapCall) { + this._call = call; + } +} + +export class MakeBatchSwapCallKeysStruct extends ethereum.Tuple { + get currency0(): Address { + return this[0].toAddress(); + } + + get currency1(): Address { + return this[1].toAddress(); + } + + get fee(): i32 { + return this[2].toI32(); + } + + get tickSpacing(): i32 { + return this[3].toI32(); + } + + get hooks(): Address { + return this[4].toAddress(); + } +} + +export class MakeSwapCall extends ethereum.Call { + get inputs(): MakeSwapCall__Inputs { + return new MakeSwapCall__Inputs(this); + } + + get outputs(): MakeSwapCall__Outputs { + return new MakeSwapCall__Outputs(this); + } +} + +export class MakeSwapCall__Inputs { + _call: MakeSwapCall; + + constructor(call: MakeSwapCall) { + this._call = call; + } + + get key(): MakeSwapCallKeyStruct { + return changetype( + this._call.inputValues[0].value.toTuple(), + ); + } + + get amountSpecified(): BigInt { + return this._call.inputValues[1].value.toBigInt(); + } + + get zeroForOne(): boolean { + return this._call.inputValues[2].value.toBoolean(); + } +} + +export class MakeSwapCall__Outputs { + _call: MakeSwapCall; + + constructor(call: MakeSwapCall) { + this._call = call; + } +} + +export class MakeSwapCallKeyStruct extends ethereum.Tuple { + get currency0(): Address { + return this[0].toAddress(); + } + + get currency1(): Address { + return this[1].toAddress(); + } + + get fee(): i32 { + return this[2].toI32(); + } + + get tickSpacing(): i32 { + return this[3].toI32(); + } + + get hooks(): Address { + return this[4].toAddress(); + } +} diff --git a/donations/generated/schema.ts b/donations/generated/schema.ts new file mode 100644 index 0000000..765c51e --- /dev/null +++ b/donations/generated/schema.ts @@ -0,0 +1,352 @@ +// THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. + +import { + TypedMap, + Entity, + Value, + ValueKind, + store, + Bytes, + BigInt, + BigDecimal, +} from "@graphprotocol/graph-ts"; + +export class CampaignClosed extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save CampaignClosed entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type CampaignClosed must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("CampaignClosed", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): CampaignClosed | null { + return changetype( + store.get_in_block("CampaignClosed", id.toHexString()), + ); + } + + static load(id: Bytes): CampaignClosed | null { + return changetype( + store.get("CampaignClosed", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get campaignId(): BigInt { + let value = this.get("campaignId"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set campaignId(value: BigInt) { + this.set("campaignId", Value.fromBigInt(value)); + } + + get blockNumber(): BigInt { + let value = this.get("blockNumber"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set blockNumber(value: BigInt) { + this.set("blockNumber", Value.fromBigInt(value)); + } + + get blockTimestamp(): BigInt { + let value = this.get("blockTimestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set blockTimestamp(value: BigInt) { + this.set("blockTimestamp", Value.fromBigInt(value)); + } + + get transactionHash(): Bytes { + let value = this.get("transactionHash"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transactionHash(value: Bytes) { + this.set("transactionHash", Value.fromBytes(value)); + } +} + +export class CampaignCreated extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save CampaignCreated entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type CampaignCreated must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("CampaignCreated", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): CampaignCreated | null { + return changetype( + store.get_in_block("CampaignCreated", id.toHexString()), + ); + } + + static load(id: Bytes): CampaignCreated | null { + return changetype( + store.get("CampaignCreated", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get campaignId(): BigInt { + let value = this.get("campaignId"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set campaignId(value: BigInt) { + this.set("campaignId", Value.fromBigInt(value)); + } + + get campaignOwner(): Bytes { + let value = this.get("campaignOwner"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set campaignOwner(value: Bytes) { + this.set("campaignOwner", Value.fromBytes(value)); + } + + get campaignName(): string { + let value = this.get("campaignName"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toString(); + } + } + + set campaignName(value: string) { + this.set("campaignName", Value.fromString(value)); + } + + get blockNumber(): BigInt { + let value = this.get("blockNumber"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set blockNumber(value: BigInt) { + this.set("blockNumber", Value.fromBigInt(value)); + } + + get blockTimestamp(): BigInt { + let value = this.get("blockTimestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set blockTimestamp(value: BigInt) { + this.set("blockTimestamp", Value.fromBigInt(value)); + } + + get transactionHash(): Bytes { + let value = this.get("transactionHash"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transactionHash(value: Bytes) { + this.set("transactionHash", Value.fromBytes(value)); + } +} + +export class DonationReceived extends Entity { + constructor(id: Bytes) { + super(); + this.set("id", Value.fromBytes(id)); + } + + save(): void { + let id = this.get("id"); + assert(id != null, "Cannot save DonationReceived entity without an ID"); + if (id) { + assert( + id.kind == ValueKind.BYTES, + `Entities of type DonationReceived must have an ID of type Bytes but the id '${id.displayData()}' is of type ${id.displayKind()}`, + ); + store.set("DonationReceived", id.toBytes().toHexString(), this); + } + } + + static loadInBlock(id: Bytes): DonationReceived | null { + return changetype( + store.get_in_block("DonationReceived", id.toHexString()), + ); + } + + static load(id: Bytes): DonationReceived | null { + return changetype( + store.get("DonationReceived", id.toHexString()), + ); + } + + get id(): Bytes { + let value = this.get("id"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set id(value: Bytes) { + this.set("id", Value.fromBytes(value)); + } + + get campaignId(): BigInt { + let value = this.get("campaignId"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set campaignId(value: BigInt) { + this.set("campaignId", Value.fromBigInt(value)); + } + + get donor(): Bytes { + let value = this.get("donor"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set donor(value: Bytes) { + this.set("donor", Value.fromBytes(value)); + } + + get tokenAmounts(): Array { + let value = this.get("tokenAmounts"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigIntArray(); + } + } + + set tokenAmounts(value: Array) { + this.set("tokenAmounts", Value.fromBigIntArray(value)); + } + + get blockNumber(): BigInt { + let value = this.get("blockNumber"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set blockNumber(value: BigInt) { + this.set("blockNumber", Value.fromBigInt(value)); + } + + get blockTimestamp(): BigInt { + let value = this.get("blockTimestamp"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBigInt(); + } + } + + set blockTimestamp(value: BigInt) { + this.set("blockTimestamp", Value.fromBigInt(value)); + } + + get transactionHash(): Bytes { + let value = this.get("transactionHash"); + if (!value || value.kind == ValueKind.NULL) { + throw new Error("Cannot return null for a required field."); + } else { + return value.toBytes(); + } + } + + set transactionHash(value: Bytes) { + this.set("transactionHash", Value.fromBytes(value)); + } +} diff --git a/packages/nextjs/app/campaign/[id]/page.tsx b/packages/nextjs/app/campaign/[id]/page.tsx index 83da4bb..b725274 100644 --- a/packages/nextjs/app/campaign/[id]/page.tsx +++ b/packages/nextjs/app/campaign/[id]/page.tsx @@ -11,7 +11,7 @@ const CampaignPage = ({ params }: { params: { id: string } }) => { return ( <> -
+
diff --git a/packages/nextjs/components/Campaigns.tsx b/packages/nextjs/components/Campaigns.tsx index 0030a8d..4bfee7a 100644 --- a/packages/nextjs/components/Campaigns.tsx +++ b/packages/nextjs/components/Campaigns.tsx @@ -51,7 +51,7 @@ useEffect(() => { return ( -
+
{campaigns.map((campaign) => (

40%

-

{donationGoal} USDC

+

{donationGoal} USDC

diff --git a/packages/nextjs/components/Header.tsx b/packages/nextjs/components/Header.tsx index 9549367..d6055e5 100644 --- a/packages/nextjs/components/Header.tsx +++ b/packages/nextjs/components/Header.tsx @@ -96,12 +96,14 @@ export const Header = () => { )}
-
- SE2 logo -
-
- Scaffold-ETH - Ethereum dev stack +
+ Donation Appreciation logo
    diff --git a/packages/nextjs/components/Info.tsx b/packages/nextjs/components/Info.tsx new file mode 100644 index 0000000..6234b9e --- /dev/null +++ b/packages/nextjs/components/Info.tsx @@ -0,0 +1,145 @@ +"use client"; + +import React from "react"; + +/** + * Site header + */ +export const Info = () => { + return ( +
    +

    + Unlike other donation dApp, this one accepts all kids of ERC20 tokens! All the memecoins, barely-worth-it + airdrops and random legacy coins usually just lie in out wallets. With Donation Appreciation, we can put them + all in one pile and have them do some good in the world. +

    +

    How it works?

    + +
      +
    • + Onchain fundraisers can easily be created through our website. +
    • + +
    • + Donors can see all the ERC20s in their wallet and donate multiple ones at once. +
    • + +
    • + + Once the pile of the donated tokens reaches the target value, either by price appreciation or donations, it + all gets converted to USDC and sent to the donation address. + +
    • +
    + +

    What are the advantages

    + +
      +
    • + Enables donations in almost any ERC20 token +
    • + +
    • + Small donation today could turn into a big one later +
    • + +
    • + Fully permission-less onchain donations +
    • + +
    • + Can solve tax implications of airdrops for the donors +
    • +
    + +

    Under the hood

    + +
      +
    • + + The Graph subgraph was built to monitor the contracts of the fundraising campaigns + +
    • + +
    • + + We have built a custom EigenLayer AVS to verify the target is reached before swapping all ERC20 + tokens to $USDC + +
    • + +
    • + + UniSwap hooks are used to swap all tokens for USDC, before transferring the USDC to the donation + recipient address + +
    • +
    + + {/* Tech Used */} + +

    Tech Used

    + +
    +
    + Logo 1 +
    +
    + Logo 2 +
    +
    + Logo 3 +
    +
    + Logo 4 +
    +
    + + {/* Built by at at */} + +
    + + +
    +

    Source Code

    + + Logo 1 + +
    + +
    +

    Build at

    +
    + + Logo 4 + +
    + +
    +
    + +

    Team

    + +

    Built at

    +
    + ); +}; diff --git a/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx b/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx index 05273c2..0306232 100644 --- a/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx +++ b/packages/nextjs/components/ScaffoldEthAppWithProviders.tsx @@ -8,6 +8,7 @@ import { Toaster } from "react-hot-toast"; import { WagmiProvider } from "wagmi"; import { Footer } from "~~/components/Footer"; import { Header } from "~~/components/Header"; +import { Info } from "~~/components/Info"; import { BlockieAvatar } from "~~/components/scaffold-eth"; import { ProgressBar } from "~~/components/scaffold-eth/ProgressBar"; import { useNativeCurrencyPrice } from "~~/hooks/scaffold-eth"; @@ -28,7 +29,8 @@ const ScaffoldEthApp = ({ children }: { children: React.ReactNode }) => { <>
    -
    {children}
    +
    {children}
    +
    diff --git a/packages/nextjs/public/DA-logo.png b/packages/nextjs/public/DA-logo.png new file mode 100644 index 0000000..ab4dfed Binary files /dev/null and b/packages/nextjs/public/DA-logo.png differ diff --git a/packages/nextjs/public/eigen.jpg b/packages/nextjs/public/eigen.jpg new file mode 100644 index 0000000..5f96f20 Binary files /dev/null and b/packages/nextjs/public/eigen.jpg differ diff --git a/packages/nextjs/public/ethprague.jpeg b/packages/nextjs/public/ethprague.jpeg new file mode 100644 index 0000000..043afd9 Binary files /dev/null and b/packages/nextjs/public/ethprague.jpeg differ diff --git a/packages/nextjs/public/favicon.png b/packages/nextjs/public/favicon.png index 4bef7f2..1dd4a38 100644 Binary files a/packages/nextjs/public/favicon.png and b/packages/nextjs/public/favicon.png differ diff --git a/packages/nextjs/public/github.png b/packages/nextjs/public/github.png new file mode 100644 index 0000000..3cad90e Binary files /dev/null and b/packages/nextjs/public/github.png differ diff --git a/packages/nextjs/public/the-graph.jpeg b/packages/nextjs/public/the-graph.jpeg new file mode 100644 index 0000000..6b4c9ec Binary files /dev/null and b/packages/nextjs/public/the-graph.jpeg differ diff --git a/packages/nextjs/public/uniswap.jpeg b/packages/nextjs/public/uniswap.jpeg new file mode 100644 index 0000000..d3b2db3 Binary files /dev/null and b/packages/nextjs/public/uniswap.jpeg differ diff --git a/packages/nextjs/public/uniswap.png b/packages/nextjs/public/uniswap.png new file mode 100644 index 0000000..81d00fa Binary files /dev/null and b/packages/nextjs/public/uniswap.png differ diff --git a/packages/nextjs/tailwind.config.js b/packages/nextjs/tailwind.config.js index 9099dc5..04a8695 100644 --- a/packages/nextjs/tailwind.config.js +++ b/packages/nextjs/tailwind.config.js @@ -3,25 +3,26 @@ module.exports = { content: ["./app/**/*.{js,ts,jsx,tsx}", "./components/**/*.{js,ts,jsx,tsx}", "./utils/**/*.{js,ts,jsx,tsx}"], plugins: [require("daisyui")], darkTheme: "dark", + // lightTheme: "lemonade", darkMode: ["selector", "[data-theme='dark']"], // DaisyUI theme colors daisyui: { themes: [ { light: { - primary: "#93BBFB", + primary: "#2DCD62", "primary-content": "#212638", - secondary: "#DAE8FF", + secondary: "#EAFBEF", "secondary-content": "#212638", - accent: "#93BBFB", + accent: "#2DCD62", "accent-content": "#212638", neutral: "#212638", "neutral-content": "#ffffff", "base-100": "#ffffff", "base-200": "#f4f8ff", - "base-300": "#DAE8FF", + "base-300": "#EAFBEF", "base-content": "#212638", - info: "#93BBFB", + info: "#2DCD62", success: "#34EEB6", warning: "#FFCF72", error: "#FF8863",