-
Notifications
You must be signed in to change notification settings - Fork 4
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
* feat: add bridged collections to event cache * wip * feat: add bridged NFTs page * fix: build errors * feat: add account history to header * fix: header style
- Loading branch information
1 parent
7565f66
commit adac074
Showing
27 changed files
with
1,278 additions
and
388 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1 @@ | ||
export const L1ERC721Bridge = [{"inputs":[{"internalType":"address","name":"_messenger","type":"address"},{"internalType":"address","name":"_otherBridge","type":"address"}],"stateMutability":"nonpayable","type":"constructor"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"localToken","type":"address"},{"indexed":true,"internalType":"address","name":"remoteToken","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"ERC721BridgeFinalized","type":"event"},{"anonymous":false,"inputs":[{"indexed":true,"internalType":"address","name":"localToken","type":"address"},{"indexed":true,"internalType":"address","name":"remoteToken","type":"address"},{"indexed":true,"internalType":"address","name":"from","type":"address"},{"indexed":false,"internalType":"address","name":"to","type":"address"},{"indexed":false,"internalType":"uint256","name":"tokenId","type":"uint256"},{"indexed":false,"internalType":"bytes","name":"extraData","type":"bytes"}],"name":"ERC721BridgeInitiated","type":"event"},{"inputs":[],"name":"MESSENGER","outputs":[{"internalType":"contract CrossDomainMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"OTHER_BRIDGE","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[{"internalType":"address","name":"_localToken","type":"address"},{"internalType":"address","name":"_remoteToken","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint32","name":"_minGasLimit","type":"uint32"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"bridgeERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_localToken","type":"address"},{"internalType":"address","name":"_remoteToken","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"uint32","name":"_minGasLimit","type":"uint32"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"bridgeERC721To","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[{"internalType":"address","name":"_localToken","type":"address"},{"internalType":"address","name":"_remoteToken","type":"address"},{"internalType":"address","name":"_from","type":"address"},{"internalType":"address","name":"_to","type":"address"},{"internalType":"uint256","name":"_tokenId","type":"uint256"},{"internalType":"bytes","name":"_extraData","type":"bytes"}],"name":"finalizeBridgeERC721","outputs":[],"stateMutability":"nonpayable","type":"function"},{"inputs":[],"name":"messenger","outputs":[{"internalType":"contract CrossDomainMessenger","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"otherBridge","outputs":[{"internalType":"address","name":"","type":"address"}],"stateMutability":"view","type":"function"},{"inputs":[],"name":"version","outputs":[{"internalType":"string","name":"","type":"string"}],"stateMutability":"view","type":"function"}] as const; | ||
export const L2ERC721BridgeAbi = [{ "inputs": [{ "internalType": "address", "name": "_messenger", "type": "address" }, { "internalType": "address", "name": "_otherBridge", "type": "address" }], "stateMutability": "nonpayable", "type": "constructor" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "localToken", "type": "address" }, { "indexed": true, "internalType": "address", "name": "remoteToken", "type": "address" }, { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": false, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "tokenId", "type": "uint256" }, { "indexed": false, "internalType": "bytes", "name": "extraData", "type": "bytes" }], "name": "ERC721BridgeFinalized", "type": "event" }, { "anonymous": false, "inputs": [{ "indexed": true, "internalType": "address", "name": "localToken", "type": "address" }, { "indexed": true, "internalType": "address", "name": "remoteToken", "type": "address" }, { "indexed": true, "internalType": "address", "name": "from", "type": "address" }, { "indexed": false, "internalType": "address", "name": "to", "type": "address" }, { "indexed": false, "internalType": "uint256", "name": "tokenId", "type": "uint256" }, { "indexed": false, "internalType": "bytes", "name": "extraData", "type": "bytes" }], "name": "ERC721BridgeInitiated", "type": "event" }, { "inputs": [], "name": "MESSENGER", "outputs": [{ "internalType": "contract CrossDomainMessenger", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "OTHER_BRIDGE", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_localToken", "type": "address" }, { "internalType": "address", "name": "_remoteToken", "type": "address" }, { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, { "internalType": "uint32", "name": "_minGasLimit", "type": "uint32" }, { "internalType": "bytes", "name": "_extraData", "type": "bytes" }], "name": "bridgeERC721", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_localToken", "type": "address" }, { "internalType": "address", "name": "_remoteToken", "type": "address" }, { "internalType": "address", "name": "_to", "type": "address" }, { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, { "internalType": "uint32", "name": "_minGasLimit", "type": "uint32" }, { "internalType": "bytes", "name": "_extraData", "type": "bytes" }], "name": "bridgeERC721To", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [{ "internalType": "address", "name": "_localToken", "type": "address" }, { "internalType": "address", "name": "_remoteToken", "type": "address" }, { "internalType": "address", "name": "_from", "type": "address" }, { "internalType": "address", "name": "_to", "type": "address" }, { "internalType": "uint256", "name": "_tokenId", "type": "uint256" }, { "internalType": "bytes", "name": "_extraData", "type": "bytes" }], "name": "finalizeBridgeERC721", "outputs": [], "stateMutability": "nonpayable", "type": "function" }, { "inputs": [], "name": "messenger", "outputs": [{ "internalType": "contract CrossDomainMessenger", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "otherBridge", "outputs": [{ "internalType": "address", "name": "", "type": "address" }], "stateMutability": "view", "type": "function" }, { "inputs": [], "name": "version", "outputs": [{ "internalType": "string", "name": "", "type": "string" }], "stateMutability": "view", "type": "function" }] as const; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,4 +1,4 @@ | ||
export const OptimismMintableERC721Factory = [ | ||
export const OptimismMintableERC721FactoryAbi = [ | ||
{ | ||
inputs: [ | ||
{ | ||
|
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,3 @@ | ||
export * from "./L1ERC721Bridge" | ||
export * from "./L2ERC721Bridge" | ||
export * from "./OptimismMintableERC721Factory" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,21 @@ | ||
import { createPublicClient, http } from 'viem'; | ||
import { mainnet, sepolia } from "viem/chains"; | ||
|
||
|
||
const mainnetPublicClient = createPublicClient({ | ||
chain: mainnet, | ||
transport: http(process.env.PONDER_RPC_URL_1) | ||
}) | ||
|
||
const sepoliaPublicClient = createPublicClient({ | ||
chain: sepolia, | ||
transport: http(process.env.PONDER_RPC_URL_11155111) | ||
}) | ||
|
||
export function getL1PublicClient(l2chainId: number) { | ||
if (l2chainId === 11155420 || l2chainId === 84532) { | ||
return sepoliaPublicClient; | ||
} else { | ||
return mainnetPublicClient; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1 +1,2 @@ | ||
export const OPTIMISM_MINTABLE_ERC721_FACTORY_ADDRESS = "0x4200000000000000000000000000000000000017" | ||
export const OPTIMISM_MINTABLE_ERC721_FACTORY_ADDRESS = "0x4200000000000000000000000000000000000017" | ||
export const OPTIMISM_L2_ERC721_BRIDGE_ADDRESS = "0x4200000000000000000000000000000000000014" |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,101 @@ | ||
import { ponder } from "@/generated"; | ||
import { base, baseSepolia, optimism, optimismSepolia } from "viem/chains"; | ||
|
||
function getL2ChainId(l1ContractAddress: string | null) { | ||
if (!l1ContractAddress) { | ||
throw new Error("Invalid l1 contract Address") | ||
} | ||
const l1ContractToChainId: Record<string, number> = { | ||
"0x5a7749f83b81B301cAb5f48EB8516B986DAef23D": optimism.id, | ||
"0x608d94945A64503E642E6370Ec598e519a2C1E53": base.id, | ||
"0xd83e03D576d23C9AEab8cC44Fa98d058D2176D1f": optimismSepolia.id, | ||
"0x21eFD066e581FA55Ef105170Cc04d74386a09190": baseSepolia.id | ||
|
||
} | ||
const l2ChainId = l1ContractToChainId?.[l1ContractAddress] | ||
if (!l2ChainId) { | ||
throw new Error("Invalid l1 contract Address: " + l1ContractAddress) | ||
} | ||
return l2ChainId | ||
} | ||
|
||
|
||
ponder.on("L1ERC721Bridge:ERC721BridgeInitiated", async ({ event, context }) => { | ||
const { BridgedErc721 } = context.db; | ||
const timestamp = event.block.timestamp | ||
const chainId = context.network.chainId | ||
const { localToken: l1Token, remoteToken: l2Token, tokenId, to } = event.args | ||
const l1ContractAddress = event.log.address | ||
const l1ChainId = chainId | ||
const l2ChainId = getL2ChainId(l1ContractAddress) | ||
const id = `${l1ChainId}:${l1Token}:${tokenId}` | ||
|
||
const existingBridgedToken = await BridgedErc721.findUnique({ | ||
id, | ||
}); | ||
|
||
// Only update the token if it is the most recent event | ||
if (!existingBridgedToken || timestamp > existingBridgedToken.timestamp) { | ||
await BridgedErc721.upsert({ | ||
id, | ||
create: { | ||
state: "PENDING_TO_L2", | ||
l1ChainId, | ||
owner: to, | ||
l1Token, | ||
timestamp, | ||
l2Token, | ||
tokenId: tokenId.toString(), | ||
l2ChainId, | ||
txHash: event.log.transactionHash, | ||
txChainId: chainId | ||
}, | ||
update: { | ||
state: "PENDING_TO_L2", | ||
txHash: event.log.transactionHash, | ||
txChainId: chainId | ||
} | ||
}); | ||
} | ||
|
||
|
||
}); | ||
|
||
ponder.on("L1ERC721Bridge:ERC721BridgeFinalized", async ({ event, context }) => { | ||
const { BridgedErc721 } = context.db; | ||
const timestamp = event.block.timestamp | ||
const chainId = context.network.chainId | ||
const l1ContractAddress = event.log.address | ||
const { localToken: l1Token, remoteToken: l2Token, tokenId, to } = event.args | ||
const l1ChainId = chainId | ||
const l2ChainId = getL2ChainId(l1ContractAddress) | ||
const id = `${l1ChainId}:${l1Token}:${tokenId}` | ||
|
||
const existingBridgedToken = await BridgedErc721.findUnique({ | ||
id, | ||
}); | ||
|
||
// Only update the token if it is the most recent event | ||
if (!existingBridgedToken || timestamp > existingBridgedToken.timestamp) { | ||
await BridgedErc721.upsert({ | ||
id, | ||
create: { | ||
state: "L1", | ||
l1ChainId, | ||
owner: to, | ||
l1Token, | ||
timestamp, | ||
l2Token, | ||
tokenId: tokenId.toString(), | ||
l2ChainId, | ||
txHash: event.log.transactionHash, | ||
txChainId: chainId | ||
}, | ||
update: { | ||
state: "L1", | ||
txHash: event.log.transactionHash, | ||
txChainId: chainId | ||
} | ||
}); | ||
} | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,89 @@ | ||
import { ponder } from "@/generated"; | ||
import { base, baseSepolia, mainnet, optimism, optimismSepolia, sepolia } from "viem/chains"; | ||
|
||
function getL1ChainId(l2ChainId: number) { | ||
const productionChains: number[] = [base.id, optimism.id] | ||
const testnetChains: number[] = [baseSepolia.id, optimismSepolia.id] | ||
|
||
if (productionChains.includes(l2ChainId)) { | ||
return mainnet.id | ||
} | ||
if (testnetChains.includes(l2ChainId)) { | ||
return sepolia.id | ||
} | ||
throw new Error("Invalid l2 chain id abc: " + l2ChainId) | ||
} | ||
|
||
ponder.on("L2ERC721Bridge:ERC721BridgeInitiated", async ({ event, context }) => { | ||
const { BridgedErc721 } = context.db; | ||
const chainId = context.network.chainId | ||
const timestamp = event.block.timestamp | ||
const { remoteToken: l1Token, localToken: l2Token, tokenId } = event.args | ||
const l1ChainId = getL1ChainId(chainId) | ||
const l2ChainId = chainId | ||
const id = `${l1ChainId}:${l1Token}:${tokenId}` | ||
|
||
const existingToken = await BridgedErc721.findUnique({ | ||
id, | ||
}); | ||
|
||
if (!existingToken || timestamp > existingToken.timestamp) { | ||
await BridgedErc721.upsert({ | ||
id, | ||
update: { | ||
state: "PENDING_TO_L1", | ||
txHash: event.log.transactionHash, | ||
txChainId: chainId | ||
}, | ||
create: { | ||
state: "PENDING_TO_L1", | ||
l1ChainId, | ||
l2ChainId, | ||
l2Token, | ||
owner: event.args.to, | ||
l1Token, | ||
timestamp, | ||
tokenId: tokenId.toString(), | ||
txHash: event.log.transactionHash, | ||
txChainId: chainId | ||
} | ||
}); | ||
} | ||
}); | ||
|
||
ponder.on("L2ERC721Bridge:ERC721BridgeFinalized", async ({ event, context }) => { | ||
const { BridgedErc721 } = context.db; | ||
const chainId = context.network.chainId | ||
const timestamp = event.block.timestamp | ||
const { remoteToken: l1Token, localToken: l2Token, tokenId } = event.args | ||
const l1ChainId = getL1ChainId(chainId) | ||
const l2ChainId = chainId | ||
const id = `${l1ChainId}:${l1Token}:${tokenId}` | ||
|
||
const existingToken = await BridgedErc721.findUnique({ | ||
id, | ||
}); | ||
|
||
if (!existingToken || timestamp > existingToken.timestamp) { | ||
await BridgedErc721.upsert({ | ||
id, | ||
update: { | ||
state: "L2", | ||
txHash: event.log.transactionHash, | ||
txChainId: chainId | ||
}, | ||
create: { | ||
state: "L2", | ||
l1ChainId, | ||
l2ChainId, | ||
l2Token, | ||
owner: event.args.to, | ||
l1Token, | ||
timestamp, | ||
tokenId: tokenId.toString(), | ||
txHash: event.log.transactionHash, | ||
txChainId: chainId | ||
} | ||
}); | ||
} | ||
}); |
Oops, something went wrong.