jediswap.js
1 import { hash } from "https://esm.run/starknet@5.14"; 2 3 const PAIR_CREATED = selector("PairCreated"); 4 const UPGRADED = selector("Upgraded"); 5 const ADMIN_CHANGED = selector("AdminChanged"); 6 const BURN = selector("Burn"); 7 const MINT = selector("Mint"); 8 const SWAP = selector("Swap"); 9 const SYNC = selector("Sync"); 10 const APPROVAL = selector("Approval"); 11 const TRANSFER = selector("Transfer"); 12 13 // Stream `PairCreated` events from JediSwap. 14 export const filter = { 15 header: { weak: true }, 16 events: [ 17 { 18 fromAddress: 19 "0x00dad44c139a476c7a17fc8141e6db680e9abc9f56fe249a105094c44382c2fd", 20 keys: [PAIR_CREATED], 21 includeReceipt: false, 22 }, 23 ], 24 }; 25 26 // Export a `factory` function to enable factory mode. 27 // This function is called with data from the `filter` above 28 // and returns a filter that is used to stream child data. 29 // Filters from subsequent calls to `factory` are merged. 30 export function factory({ header, events }) { 31 // Create a filter with events for all pools created in this block. 32 const poolEvents = events.flatMap(({ event }) => { 33 const pairAddress = event.data[2]; 34 return [ 35 UPGRADED, 36 ADMIN_CHANGED, 37 BURN, 38 MINT, 39 SWAP, 40 SYNC, 41 APPROVAL, 42 TRANSFER, 43 ].map((eventKey) => ({ 44 fromAddress: pairAddress, 45 keys: [eventKey], 46 includeReceipt: false, 47 })); 48 }); 49 50 // Insert data about the pools created in this block. 51 // Values returned in `data` are handled like values returned from 52 // `transform`. 53 const pools = events.flatMap(({ event, transaction }) => { 54 const token0 = event.data[0]; 55 const token1 = event.data[1]; 56 const pairAddress = event.data[2]; 57 return { 58 type: "PairCreated", 59 createdAt: header.timestamp, 60 createdAtBlockNumber: +header.blockNumber, 61 createdAtTxHash: transaction.meta.hash, 62 pairId: pairAddress, 63 token0Id: token0, 64 token1Id: token1, 65 }; 66 }); 67 68 return { 69 filter: { 70 header: { weak: true }, 71 events: poolEvents, 72 }, 73 data: pools, 74 }; 75 } 76 77 // The transform function is invoked with data from the child filter 78 // created by the factory function above. 79 export function transform({ header, events }) { 80 return events.flatMap(({ event, transaction }) => { 81 const txMeta = { 82 pairId: event.fromAddress, 83 createdAt: header.timestamp, 84 createdAtBlockNumber: +header.blockNumber, 85 createdAtTxHash: transaction.meta.hash, 86 }; 87 88 switch (event.keys[0]) { 89 case UPGRADED: 90 return { 91 type: "Upgraded", 92 ...txMeta, 93 }; 94 case ADMIN_CHANGED: 95 return { 96 type: "AdminChanged", 97 ...txMeta, 98 }; 99 case BURN: 100 return { 101 type: "Burn", 102 ...txMeta, 103 }; 104 case MINT: 105 return { 106 type: "Mint", 107 ...txMeta, 108 }; 109 case SWAP: 110 return { 111 type: "Swap", 112 ...txMeta, 113 }; 114 case SYNC: 115 return { 116 type: "Sync", 117 ...txMeta, 118 }; 119 case APPROVAL: 120 return { 121 type: "Approval", 122 ...txMeta, 123 }; 124 case TRANSFER: 125 return { 126 type: "Transfer", 127 ...txMeta, 128 }; 129 default: 130 console.log("UNKNOWN"); 131 return []; 132 } 133 }); 134 } 135 136 // Pad selector to match DNA felt length. 137 function selector(name) { 138 const bn = BigInt(hash.getSelectorFromName(name)); 139 const padded = bn.toString(16).padStart(64, "0"); 140 return "0x" + padded; 141 }