diff --git a/.gitignore b/.gitignore index ee07ced4..ca8d9fde 100644 --- a/.gitignore +++ b/.gitignore @@ -14,7 +14,6 @@ packages/hardhat/cache docker/**/data -packages/subgraph/config/config.json tenderly.yaml # dependencies diff --git a/packages/subgraph/config/config.json b/packages/subgraph/config/config.json new file mode 100644 index 00000000..4b4a6337 --- /dev/null +++ b/packages/subgraph/config/config.json @@ -0,0 +1,406 @@ +{ + "streams": [ + { + "name": "bboyle.eth", + "role": "", + "address": "0xdfcbf02520fdde9d8c46cc44dadcfc798029e5b4", + "github": "", + "builds": [], + "streamAddress": "0x684653eF9231e6142446053E4766027e6c6aAb15", + "streamUrl": "http://bboyle.buidlguidl.com" + }, + { + "name": "frogbaseball.eth", + "role": "", + "address": "0x38f84e92b468a1885e73cedc9a4d5632de07eabb", + "github": "", + "builds": [], + "streamAddress": "0x664C54cF70797a69f82A4991Ea1Be343a03334e8", + "streamUrl": "http://frogbaseball.buidlguidl.com" + }, + { + "name": "kijun.eth", + "role": "", + "address": "0x03d8DF325C8bFB8929414756E95023d2150C8881", + "github": "", + "builds": [], + "streamAddress": "0x8DaBdEf0259A8266234fcbDE4b12a59A66559239", + "streamUrl": "https://kijun.buidlguidl.com/" + }, + { + "name": "huxwell.eth", + "role": "", + "address": "0xc9a238405ef9d753d55ec1eb8f7a7b17b8d83e63", + "github": "", + "builds": [], + "streamAddress": "0xE29ae83beF493eae7A6c07608C25C359d24989C3", + "streamUrl": "http://huxwell.buidlguidl.com" + }, + { + "name": "grothe.eth", + "role": "", + "address": "0xacf16886efa51ff0957ef321b8510e53d67d1d7c", + "github": "", + "builds": [], + "streamAddress": "0xeAdc8bBB8717765429712C7BF5C9C5e55f0bCCd5", + "streamUrl": "http://grothe.buidlguidl.com" + }, + + { + "name": "cluda.eth", + "role": "", + "address": "0xEB0C4F040FF0e2278bB2c14B7CC9c357467C83e3", + "github": "", + "builds": [], + "streamAddress": "0xB34006e71Ac4cF8B05C56422B7Be3d7f14d934E8", + "streamUrl": "http://cluda.buidlguidl.com" + }, + { + "name": "danielrees.eth", + "role": "", + "address": "0xE7A54673f2FfE41cf38dbA2014326064A958b709", + "github": "", + "builds": [], + "streamAddress": "0xA13966b1b4B66aC6670f0C14f8FA0a45FE219A09", + "streamUrl": "http://danielrees.buidlguidl.com" + }, + { + "name": "stermi.eth", + "role": "fullstack", + "address": "0x67960c0c99498AfF880D1bd68FE596C9443528ae", + "github": "", + "builds": [], + "streamAddress": "0x3B2ca03Bae949bA2C72C78D2f331b5Ebd155c735", + "streamUrl": "http://stermi.buidlguidl.com" + }, + { + "name": "damianmarti.eth", + "role": "fullstack", + "address": "0x5dCb5f4F39Caa6Ca25380cfc42280330b49d3c93", + "github": "", + "builds": [], + "streamAddress": "0x8FE72B655b54f4a900b1A0e6FD9957a6a3779209", + "streamUrl": "http://damianmarti.buidlguidl.com" + }, + { + "name": "mridul.eth", + "role": "fullstack", + "address": "0x5AbB06DC717cbe8112eFf232a6dfc98cB521511d", + "github": "", + "builds": [], + "streamAddress": "0x4cc7976d1b0784808E838CD89e0A4dF957B0f652", + "streamUrl": "http://mridul.buidlguidl.com" + }, + + { + "name": "developermarwan.eth", + "role": "fullstack", + "address": "0x53E7f107F3037Df2A03C79Fa9750908c67B55CD3", + "github": "", + "builds": [], + "streamAddress": "0x52864De6545554437999FA20374AFf409B4F52b7", + "streamUrl": "http://developermarwan.buidlguidl.com" + }, + { + "name": "dgrcode.eth", + "role": "fullstack", + "address": "0x0D0f9Ebd254e510AA6F3788ecb6E6fC8bf78188F", + "github": "", + "builds": [], + "streamAddress": "0xE5C281c470AcedD6f15d41C640988822594bf69A", + "streamUrl": "http://dgrcode.buidlguidl.com" + }, + { + "name": "carletex.eth", + "role": "fullstack", + "address": "0x60583563D5879C2E59973E5718c7DE2147971807", + "github": "", + "builds": [], + "streamAddress": "0x4b5ed9760e5F5E87c50d9739BeFf5b13FB61cC2F", + "streamUrl": "http://carletex.buidlguidl.com" + }, + { + "name": "trombone.eth", + "role": "support", + "address": "0x18EE15f0C12B3035C84a9A1027dB1e1151308ac5", + "github": "", + "builds": [], + "streamAddress": "0x853E9d7036C48FA36CCCfF0e5b8907ae013ae8Eb", + "streamUrl": "http://trombone.buidlguidl.com" + }, + { + "name": "ghostffcode.eth", + "role": "fullstack", + "address": "0xbF7877303B90297E7489AA1C067106331DfF7288", + "github": "", + "builds": [], + "streamAddress": "0x0e185D75A3658De186fCef13Ae01e816cCCE599a", + "streamUrl": "http://ghostffcode.buidlguidl.com" + }, + { + "name": "ryanpetroff.eth", + "role": "gardener", + "address": "0x00555dC77a343E205CB1C7755407c93470DB3F91", + "github": "", + "builds": [], + "streamAddress": "0x6459ED3063E1267B9c22E6410076d328E4B971a6", + "streamUrl": "http://ryanpetroff.buidlguidl.com" + }, + { + "name": "captnseagraves.eth", + "role": "fullstack", + "address": "0x5Ad3b55625553CEf54D7561cD256658537d54AAd", + "github": "https://github.com/austintgriffith/scaffold-eth/commits?author=captnseagraves", + "builds": [], + "streamAddress": "0x446455ece8922a5C4CE8b205b74D06bD9706143b", + "streamUrl": "http://captnseagraves.buidlguidl.com" + }, + { + "name": "lekag.eth", + "role": "Full Stack", + "address": "0x7C2F9E77CFB36Fc90bc8296C0cebbcd89E8D1981", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=le-kag", + "builds": [], + "streamAddress": "0xc3c9ff28Ffa2BB65E5827C5Fdc309FFC41e5017e", + "streamUrl": "http://lekag.buidlguidl.com" + }, + { + "name": "nook.eth", + "role": "Full Stack", + "address": "0x50c57894C3b9bf022D10B94B9D940a48A93cd8c0", + "github": "", + "builds": [], + "streamAddress": "0xbD0944bb3aE59952E772A65661C1a51BBbF1ea92", + "streamUrl": "http://nook.buidlguidl.com" + }, + { + "name": "blindnabler.eth", + "role": "Full Stack", + "address": "0x807a1752402D21400D555e1CD7f175566088b955", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=MercuricChloride", + "builds": [], + "streamAddress": "0x619ACcbE6E5C4E5Cc71a29a05eE7228867c9733c", + "streamUrl": "http://blindnabler.buidlguidl.com" + }, + { + "name": "0xsama.eth", + "role": "Full Stack", + "address": "0x411381D227AF243E9383fDbB77313352E622D72f", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=ososco", + "builds": [], + "streamAddress": "0x538d822559Eb7A2D594E7D68dCdf29b3296830D3", + "streamUrl": "http://0xsama.buidlguidl.com" + }, + { + "name": "xiangan.eth", + "role": "Support", + "address": "0x26Ad3416e70bD055Dbc5E34c91D17d72AdBe1478", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=shravansunder", + "builds": [], + "streamAddress": "0xb32270518664C77a09E44f6DA59aD2dd3470299C", + "streamUrl": "http://xiangan.buidlguidl.com" + }, + { + "name": "shravansunder.eth", + "role": "Full Stack", + "address": "0xbE13CA20B7ff5fEf2D04f67aBf2A2a07feAfA102", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=shravansunder", + "builds": [], + "streamAddress": "0x262f56C901847261080e366eDAb27d454a1315cd", + "streamUrl": "http://shravansunder2.buidlguidl.com" + }, + { + "name": "powvt.eth", + "role": "Full Stack", + "address": "0x9E67029403675Ee18777Ed38F9C1C5c75F7B34f2", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=powvt", + "builds": [], + "streamAddress": "0xc80bfd26B102991E2D96CE583B5eFA2E4Db0733d", + "streamUrl": "http://powvt.buidlguidl.com" + }, + { + "name": "isaacpatka.eth", + "role": "Full Stack", + "address": "0x775aF9b7c214Fe8792aB5f5da61a8708591d517E", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=ipatka", + "builds": [], + "streamAddress": "0x21BD856523f62Dd2A6eDBa750E97bD106204D5f2", + "streamUrl": "http://isaacpatka.buidlguidl.com" + }, + { + "name": "pabloruiz.eth", + "role": "Full Stack | Community", + "address": "0xfD4c0F5848642FC2041c003cb684fc66B16217bc", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=pabloruiz55", + "builds": [], + "streamAddress": "0xB3A51b63B7f1Bcb8600FF67E4a69C7B690994a89", + "streamUrl": "http://pabloruiz.buidlguidl.com" + }, + { + "name": "togzhan.eth", + "role": "Full Stack", + "address": "0x50ECcad809D553335a8eB7bfEC2CeE5A6f2cdE43", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=btogzhan2000", + "builds": [], + "streamAddress": "0x3B60b34Aa5dEAFF586D3841AD62b4aa730e11ceC", + "streamUrl": "http://togzhan.buidlguidl.com" + }, + { + "name": "ironsoul.eth", + "role": "React | Full Stack", + "address": "0x1e2Ce012b27d0c0d3e717e943EF6e62717CEc4ea", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=ironsoul0", + "builds": [ + "xnft", + "honeypot", + "dos", + "flash", + "highestbid", + "merklenft", + "paymentchannel" + ], + "streamAddress": "0xDbcD66b510191cD0539F7FAe8cD981B82Ee2006f", + "streamUrl": "http://ironsoul.buidlguidl.com" + }, + { + "name": "viraz.eth", + "role": "Full Stack", + "address": "0x2DdA8dc2f67f1eB94b250CaEFAc9De16f70c5A51", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=viraj124", + "builds": [ + "xnft", + "proxy", + "diamond", + "highestbid", + "merklenft", + "paymentchannel", + "bondingcurve" + ], + "streamAddress": "0x974a061A8cE5a2b07cB3f1D356Bb01Daaa9eC31d", + "streamUrl": "http://viraz.buidlguidl.com" + }, + { + "name": "sadda11asm.eth", + "role": "Full Stack", + "address": "0x7b945ffE9725D8e05343bEC36c0eced294097f78", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=ironsoul0", + "builds": ["xnft", "rokens", "highestbid", "merklenft", "paymentchannel"], + "streamAddress": "0x1eB6Da6F03B6D3C0d8da0B127388Add4d78Eb652", + "streamUrl": "http://sadda11asm.buidlguidl.com" + }, + { + "name": "amogh.eth", + "role": "Full Stack", + "address": "0x1245e96fe32B43dDEc930D662B5d20239282b876", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=amogh-jrules", + "builds": ["smms", "push", "metamultisig"], + "streamAddress": "0xA267be6eF185f7563354e90882c1d3332455B8F8", + "streamUrl": "http://amogh.buidlguidl.com" + }, + { + "name": "calvinquin.argent.xyz", + "role": "Full Stack", + "address": "0x614Ae4C6Eb91cEC9e6e178549c0745A827212B24", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=calvbore", + "builds": [], + "streamAddress": "0x864Fa2F20e414c9534B1DE567a30a77436c7a745", + "streamUrl": "http://calvinquin.buidlguidl.com" + }, + + { + "name": "ssteiger.eth", + "role": "React", + "address": "0x4ceb8dC70813fFbB2d8d6DC0755086698F977613", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=ssteiger", + "builds": ["ethdev"], + "streamAddress": "0x24aAc13141DbE8946433215bfdc793C2B71398c8", + "streamUrl": "http://ssteiger.buidlguidl.com" + }, + { + "name": "pharo.eth", + "role": "Maintainer | Full Stack", + "address": "0xa4ca1b15fe81f57cb2d3f686c7b13309906cd37b", + "github": "https://github.com/austintgriffith/scaffold-eth/commits?author=codenamejason", + "builds": ["vrf"], + "streamAddress": "0x3DC246459433aFc0360b83166A6Dd9B7697EaA4A", + "streamUrl": "http://rawcipher1.buidlguidl.com" + }, + { + "name": "mrdee.eth", + "role": "Artwork", + "address": "0xd2f016809969b4105978fDD5b112CD95bFDd6814", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=azf20", + "builds": [], + "streamAddress": "0xD31aDDE3c6659653f5BdCb237afB353155db1567", + "streamUrl": "http://mrdee.buidlguidl.com" + }, + { + "name": "pileofscraps.eth", + "role": "Full Stack", + "address": "0x5c43B1eD97e52d009611D89b74fA829FE4ac56b1", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=pileofscraps", + "builds": [], + "streamAddress": "0x0A9eDE9A66683F23d369FC6bAAA9D1fa7198Ebf2", + "streamUrl": "http://pileofscraps.buidlguidl.com/" + }, + { + "name": "hunterchang.eth", + "role": "React", + "address": "0xf7e89E45502890381F9242403eA8661fad89Ca79", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=azf20", + "builds": ["xnft"], + "streamAddress": "0x560Dd59ED235446d04da7C907289E3f88e685447", + "streamUrl": "http://hunterchang.buidlguidl.com" + }, + + { + "name": "hipsterhelpdesk.eth", + "role": "eth.build", + "address": "0x84946f14B092A0b32B21dd10E742C02AE3710aDd", + "github": "https://github.com/scaffold-eth/eth.build/commits?author=grahamtallen", + "builds": [], + "streamAddress": "0x04e9245892391FB290D11D5deB0bB8C2A325B629", + "streamUrl": "http://hipsterhelpdesk.buidlguidl.com" + }, + + { + "name": "adamfuller.eth", + "role": "Solidity + React", + "address": "0x60Ca282757BA67f3aDbF21F3ba2eBe4Ab3eb01fc", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=azf20", + "builds": [ + "niftyink", + "uniswapper", + "lender", + "ape", + "op", + "signatorio", + "burnyBoys" + ], + "streamAddress": "0x754A8a09Eae2FFEFbDE706a6ed40C0f0F3c58d7e", + "streamUrl": "http://adamfuller.buidlguidl.com" + }, + + { + "name": "austingriffith.eth", + "role": "Mentor", + "address": "0x34aA3F359A9D614239015126635CE7732c18fDF3", + "github": "https://github.com/scaffold-eth/scaffold-eth/commits?author=austintgriffith", + "builds": [ + "niftyink", + "simplestream", + "niftyview", + "opnfts", + "smms", + "allocator", + "radwallet", + "punkwallet", + "simplenft", + "randomimage", + "gtgs" + ], + "streamAddress": "0x518Af5F20bf07C882e17731207761C174AB4F9c4", + "streamUrl": "http://austingriffith.buidlguidl.com" + } + ] +} diff --git a/packages/subgraph/package.json b/packages/subgraph/package.json index e37ba8b3..d481841e 100644 --- a/packages/subgraph/package.json +++ b/packages/subgraph/package.json @@ -5,14 +5,14 @@ "scripts": { "codegen": "graph codegen", "build": "graph build", - "deploy": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ GITHUB_USERNAME/your-contract", + "deploy": "graph deploy --node https://api.thegraph.com/deploy/ --ipfs https://api.thegraph.com/ipfs/ azf20/buidl-guidl-streams", "create-local": "graph create --node http://localhost:8020/ scaffold-eth/your-contract", "remove-local": "graph remove --node http://localhost:8020/ scaffold-eth/your-contract", "deploy-local": "graph deploy --node http://localhost:8020/ --ipfs http://localhost:5001 scaffold-eth/your-contract" }, "dependencies": { - "@graphprotocol/graph-cli": "0.18.0", - "@graphprotocol/graph-ts": "0.18.0" + "@graphprotocol/graph-cli": "0.23.1", + "@graphprotocol/graph-ts": "0.23.2" }, "devDependencies": { "mustache": "^3.1.0" diff --git a/packages/subgraph/src/mapping.ts b/packages/subgraph/src/mapping.ts index 0e84a3d6..a0b14591 100644 --- a/packages/subgraph/src/mapping.ts +++ b/packages/subgraph/src/mapping.ts @@ -1,34 +1,98 @@ -import { BigInt, Address } from "@graphprotocol/graph-ts" +import { BigInt, Address, dataSource } from "@graphprotocol/graph-ts"; import { - YourContract, - SetPurpose -} from "../generated/YourContract/YourContract" -import { Purpose, Sender } from "../generated/schema" + Deposit as DepositEvent, + Withdraw as WithdrawalEvent, + SimpleStream, +} from "../generated/Stream/SimpleStream"; +import { + Stream, + Builder, + Funder, + Deposit, + Withdrawal, +} from "../generated/schema"; + +export function handleDeposit(event: DepositEvent): void { + let streamAddress = dataSource.address(); + + let stream = Stream.load(streamAddress.toHexString()); + + if (stream == null) { + stream = new Stream(streamAddress.toHexString()); -export function handleSetPurpose(event: SetPurpose): void { + let contract = SimpleStream.bind(streamAddress); + let builderAddress = contract.toAddress(); + let cap = contract.cap(); + let frequency = contract.frequency(); - let senderString = event.params.sender.toHexString() + stream.builder = builderAddress.toHexString(); + stream.cap = cap; + stream.frequency = frequency; + stream.createdAt = event.block.timestamp; + stream.totalDeposited = event.params.amount; + stream.totalWithdrawn = BigInt.fromI32(0); - let sender = Sender.load(senderString) + let builder = Builder.load(builderAddress.toHexString()); - if (sender == null) { - sender = new Sender(senderString) - sender.address = event.params.sender - sender.createdAt = event.block.timestamp - sender.purposeCount = BigInt.fromI32(1) + if (builder == null) { + builder = new Builder(builderAddress.toHexString()); + builder.totalWithdrawn = BigInt.fromI32(0); + builder.save(); + } + } else { + stream.totalDeposited = stream.totalDeposited.plus(event.params.amount); } - else { - sender.purposeCount = sender.purposeCount.plus(BigInt.fromI32(1)) + + let funder = Funder.load(event.params.from.toHexString()); + if (funder == null) { + funder = new Funder(event.params.from.toHexString()); + funder.totalDeposited = event.params.amount; + funder.createdAt = event.block.timestamp; + } else { + funder.totalDeposited = funder.totalDeposited.plus(event.params.amount); } - let purpose = new Purpose(event.transaction.hash.toHex() + "-" + event.logIndex.toString()) + let deposit = new Deposit( + event.transaction.hash.toHex() + "-" + event.logIndex.toString() + ); + + deposit.stream = streamAddress.toHexString(); + deposit.amount = event.params.amount; + deposit.funder = event.params.from.toHexString(); + deposit.createdAt = event.block.timestamp; + deposit.reason = event.params.reason; + deposit.transactionHash = event.transaction.hash.toHex(); + + stream.save(); + funder.save(); + deposit.save(); +} + +export function handleWithdrawal(event: WithdrawalEvent): void { + let streamAddress = dataSource.address(); + + let builder = Builder.load(event.params.to.toHexString()); + if (builder !== null) { + builder.totalWithdrawn = builder.totalWithdrawn.plus(event.params.amount); + builder.save(); + } + + let stream = Stream.load(streamAddress.toHexString()); + if (stream !== null) { + stream.totalWithdrawn = stream.totalWithdrawn.plus(event.params.amount); + stream.save(); + } - purpose.purpose = event.params.purpose - purpose.sender = senderString - purpose.createdAt = event.block.timestamp - purpose.transactionHash = event.transaction.hash.toHex() + let withdrawal = new Withdrawal( + event.transaction.hash.toHex() + "-" + event.logIndex.toString() + ); - purpose.save() - sender.save() + withdrawal.stream = streamAddress.toHexString(); + withdrawal.amount = event.params.amount; + withdrawal.builder = event.params.to.toHexString(); + withdrawal.createdAt = event.block.timestamp; + withdrawal.reason = event.params.reason; + withdrawal.transactionHash = event.transaction.hash.toHex(); + withdrawal.save(); } diff --git a/packages/subgraph/src/schema.graphql b/packages/subgraph/src/schema.graphql index acac95ac..03a664a0 100644 --- a/packages/subgraph/src/schema.graphql +++ b/packages/subgraph/src/schema.graphql @@ -1,15 +1,45 @@ -type Purpose @entity { +type Stream @entity { id: ID! - sender: Sender! - purpose: String! + builder: Builder! + cap: BigInt + frequency: BigInt createdAt: BigInt! - transactionHash: String! + deposits: [Deposit!] @derivedFrom(field: "stream") + withdrawals: [Withdrawal!] @derivedFrom(field: "stream") + totalDeposited: BigInt! + totalWithdrawn: BigInt! } -type Sender @entity { +type Builder @entity { id: ID! - address: Bytes! - purposes: [Purpose!] @derivedFrom(field: "sender") - createdAt: BigInt! - purposeCount: BigInt! + streams: [Stream!] @derivedFrom(field: "builder") + withdrawals: [Withdrawal!] @derivedFrom(field: "builder") + totalWithdrawn: BigInt! +} + +type Funder @entity { + id: ID! + createdAt: BigInt + deposits: [Deposit!] @derivedFrom(field: "funder") + totalDeposited: BigInt! +} + +type Deposit @entity { + id: ID! + stream: Stream! + funder: Funder! + createdAt: BigInt + amount: BigInt + reason: String + transactionHash: String +} + +type Withdrawal @entity { + id: ID! + stream: Stream! + builder: Builder! + createdAt: BigInt + amount: BigInt + reason: String + transactionHash: String } diff --git a/packages/subgraph/src/subgraph.template.yaml b/packages/subgraph/src/subgraph.template.yaml index 62595d09..c6352a42 100644 --- a/packages/subgraph/src/subgraph.template.yaml +++ b/packages/subgraph/src/subgraph.template.yaml @@ -2,24 +2,31 @@ specVersion: 0.0.2 schema: file: ./src/schema.graphql dataSources: + {{#streams}} - kind: ethereum/contract - name: YourContract - network: localhost + name: {{name}} + network: mainnet source: - address: '{{YourContractAddress}}' - abi: YourContract - startBlock: 1 + address: "{{streamAddress}}" + abi: SimpleStream + startBlock: 12470442 mapping: kind: ethereum/events - apiVersion: 0.0.4 + apiVersion: 0.0.5 language: wasm/assemblyscript entities: - - Purpose - - Sender + - Stream + - Builder + - Funder + - Deposit + - Withdrawal abis: - - name: YourContract - file: ./abis/YourContract.json + - name: SimpleStream + file: ./abis/SimpleStream.json eventHandlers: - - event: SetPurpose(address,string) - handler: handleSetPurpose + - event: Deposit(indexed address,uint256,string) + handler: handleDeposit + - event: Withdraw(indexed address,uint256,string) + handler: handleWithdrawal file: ./src/mapping.ts + {{/streams}}