Skip to content

Commit

Permalink
Merge pull request #634 from 1ifeworld/jawn/syn-from-scratch
Browse files Browse the repository at this point in the history
init
  • Loading branch information
0xTranqui authored Jun 25, 2024
2 parents 8ea296d + cc90894 commit 31c62c6
Show file tree
Hide file tree
Showing 9 changed files with 288 additions and 234 deletions.
68 changes: 20 additions & 48 deletions apps/site/app/api/post/route.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,32 @@
import { novaPubClient } from '@/config/publicClient'
import { Defender } from '@openzeppelin/defender-sdk'
import { ethers } from 'ethers'
import {
syndicateClientPost,
generatePostTxnInput,
projectIdPost,
} from '@/config/syndicateClient'
import type { NextRequest } from 'next/server'
import { addresses, postGatewayABI } from 'scrypt'
import type { Hex } from 'viem'

export const maxDuration = 30 // This function can run for a maximum of 30 seconds
import { waitForHash } from '@syndicateio/syndicate-node/utils'

export async function POST(req: NextRequest) {
const post = await req.json()

const credentials = {
relayerApiKey: process.env.NONCE_API_UNO,
relayerApiSecret: process.env.NONCE_SECRET_UNO,
}

try {
const defenderClient = new Defender(credentials)
const provider = defenderClient.relaySigner.getProvider()
const signer = defenderClient.relaySigner.getSigner(provider, {
speed: 'fast',
})

const postGateway = new ethers.Contract(
addresses.postGateway.nova,
postGatewayABI,
signer as unknown as ethers.Signer,
const postTx =
// biome-ignore lint:
await syndicateClientPost!.transact.sendTransaction(
generatePostTxnInput(post),
)

const tx = await postGateway.post(post)
const successfulTxHash = await waitForHash(syndicateClientPost, {
projectId: projectIdPost,
transactionId: postTx.transactionId,
})

await novaPubClient.waitForTransactionReceipt({
hash: tx.hash as Hex,
})
console.log({ successfulTxHash })

return new Response(JSON.stringify({ success: true, hash: tx.hash }), {
return new Response(
JSON.stringify({ success: true, hash: successfulTxHash }),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
})
} catch (error) {
let errorMessage = 'Unknown error'
let statusCode = 500

if (error instanceof Error) {
errorMessage = error.message
statusCode =
// biome-ignore lint: `status` is not part of the standard Error interface
typeof (error as any).status === 'number' ? (error as any).status : 500
}

return new Response(
JSON.stringify({ success: false, hash: null, error: errorMessage }),
{
status: statusCode,
headers: { 'Content-Type': 'application/json' },
},
)
}
},
)
}
70 changes: 21 additions & 49 deletions apps/site/app/api/postBatch/route.ts
Original file line number Diff line number Diff line change
@@ -1,60 +1,32 @@
import { novaPubClient } from '@/config/publicClient'
import { Defender } from '@openzeppelin/defender-sdk'
import { ethers } from 'ethers'
import type { NextRequest } from 'next/server'
import { addresses, postGatewayABI } from 'scrypt'
import type { Hex } from 'viem'

export const maxDuration = 30 // This function can run for a maximum of 30 seconds
import {
syndicateClientPost,
generatePostBatchTxnInput,
projectIdPost,
} from '@/config/syndicateClient'
import { waitForHash } from '@syndicateio/syndicate-node/utils'

export async function POST(req: NextRequest) {
const postsArray = await req.json()
console.log({ postsArray })

const credentials = {
relayerApiKey: process.env.NONCE_API_UNO,
relayerApiSecret: process.env.NONCE_SECRET_UNO,
}

try {
const defenderClient = new Defender(credentials)
const provider = defenderClient.relaySigner.getProvider()
const signer = defenderClient.relaySigner.getSigner(provider, {
speed: 'fast',
})

const postGateway = new ethers.Contract(
addresses.postGateway.nova,
postGatewayABI,
signer as unknown as ethers.Signer,
const postTx =
// biome-ignore lint:
await syndicateClientPost!.transact.sendTransaction(
generatePostBatchTxnInput(postsArray),
)

const tx = await postGateway.postBatch(postsArray)
await novaPubClient.waitForTransactionReceipt({
hash: tx.hash as Hex,
})
const successfulTxHash = await waitForHash(syndicateClientPost, {
projectId: projectIdPost,
transactionId: postTx.transactionId,
})

console.log({ successfulTxHash })

return new Response(JSON.stringify({ success: true, hash: tx.hash }), {
return new Response(
JSON.stringify({ success: true, hash: successfulTxHash }),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
})
} catch (error) {
let errorMessage = 'Unknown error'
let statusCode = 500

if (error instanceof Error) {
errorMessage = error.message
statusCode =
// biome-ignore lint: `status` is not part of the standard Error interface
typeof (error as any).status === 'number' ? (error as any).status : 500
}

return new Response(
JSON.stringify({ success: false, hash: null, error: errorMessage }),
{
status: statusCode,
headers: { 'Content-Type': 'application/json' },
},
)
}
},
)
}
121 changes: 42 additions & 79 deletions apps/site/app/api/registerFor/route.ts
Original file line number Diff line number Diff line change
@@ -1,89 +1,52 @@
import { optimismPubClient } from '@/config/publicClient'
import { Defender } from '@openzeppelin/defender-sdk'
import { ethers } from 'ethers'
import type { NextRequest } from 'next/server'
import { addresses, idRegistryABI } from 'scrypt'
import { type Hex, decodeAbiParameters } from 'viem'

export const maxDuration = 30 // This function can run for a maximum of 30 seconds
import { decodeAbiParameters } from 'viem'
import {
syndicateClientIdRegistry,
generateIdRegistryInput,
projectIdRegistry,
} from '@/config/syndicateClient'
import { waitForHash } from '@syndicateio/syndicate-node/utils'
import { optimismPubClient } from '@/config/publicClient'
import type { Hex } from 'viem'

export async function POST(req: NextRequest) {
const user = await req.json()
console.log({ user })

const { username, ...userWithoutUsername } = user
const { to, recovery, deadline, sig } = userWithoutUsername

console.log({ userWithoutUsername })
const credentials = {
relayerApiKey: process.env.IDREGISTRY_API_UNO,
relayerApiSecret: process.env.IDREGISTRY_SECRET_UNO,
}

try {
const defenderClient = new Defender(credentials)
const provider = defenderClient.relaySigner.getProvider()
const signer = defenderClient.relaySigner.getSigner(provider, {
speed: 'fast',
})

const idRegistry = new ethers.Contract(
addresses.idRegistry.optimism,
idRegistryABI,
signer as unknown as ethers.Signer,
)

const registerTxn = await idRegistry.registerFor(
to,
recovery,
deadline,
sig,
const registerTx =
// biome-ignore lint:
await syndicateClientIdRegistry!.transact.sendTransaction(
generateIdRegistryInput({ to, recovery, deadline, sig }),
)

const txnReceipt = await optimismPubClient.waitForTransactionReceipt({
hash: registerTxn.hash as Hex,
})

const [rid, recoveryAddress] = decodeAbiParameters(
[
{ name: 'rid', type: 'uint256' },
{ name: 'recoveryAddress', type: 'address' },
],
txnReceipt.logs[0].data,
)

console.log('rid: ', rid)
console.log('transaction receipt: ', registerTxn)

return new Response(
JSON.stringify({
success: true,
hash: registerTxn.hash,
rid: rid.toString(),
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
},
)
} catch (error) {
console.error(error)
let errorMessage = 'Unknown error'
let statusCode = 500

if (error instanceof Error) {
errorMessage = error.message
statusCode =
// biome-ignore lint: `status` is not part of the standard Error interface
typeof (error as any).status === 'number' ? (error as any).status : 500
}

return new Response(
JSON.stringify({ success: false, error: errorMessage }),
{
status: statusCode,
headers: { 'Content-Type': 'application/json' },
},
)
}
const successfulTxHash = await waitForHash(syndicateClientIdRegistry, {
projectId: projectIdRegistry,
transactionId: registerTx.transactionId,
})

const txnReceipt = await optimismPubClient.waitForTransactionReceipt({
hash: successfulTxHash as Hex,
})

const [rid] = decodeAbiParameters(
[
{ name: 'rid', type: 'uint256' },
{ name: 'recoveryAddress', type: 'address' },
],

txnReceipt.logs[0].data,
)

return new Response(
JSON.stringify({
success: true,
hash: successfulTxHash,
rid: rid.toString(),
}),
{
status: 200,
headers: { 'Content-Type': 'application/json' },
},
)
}
3 changes: 2 additions & 1 deletion apps/site/biome.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,8 @@
"rules": {
"recommended": true,
"style": {
"noUselessElse": "off"
"noUselessElse": "off",
"noNonNullAssertion": "off"
},
"suspicious": {
"noRedeclare": "off",
Expand Down
73 changes: 73 additions & 0 deletions apps/site/config/syndicateClient.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import { SyndicateClient } from '@syndicateio/syndicate-node'
import { addresses } from 'scrypt'

type PostMessage = {
rid: bigint
timestamp: bigint
msgType: number
msgBody: string
}

type Post = {
signer: string
message: PostMessage
hashType: number
hash: string
sigType: number
sig: string
}

type Register = {
to: string
recovery: string
deadline: number
sig: string
}

type PostBatchFunction = {
posts: Post[]
}

export const projectIdPost =
process.env.SYNDICATE_PROJECT_ID_POSTGATEWAY ?? 'Error'
export const projectIdRegistry =
process.env.SYNDICATE_PROJECT_ID_IDREGISTRY ?? 'Error'

export const generatePostBatchTxnInput = (postsArray: PostBatchFunction) => ({
projectId: projectIdPost,
contractAddress: addresses.postGateway.nova,
chainId: 42170,
functionSignature:
'postBatch((address signer, (uint256 rid, uint256 timestamp, uint8 msgType, bytes msgBody) message, uint16 hashType, bytes32 hash, uint16 sigType, bytes sig)[] posts)',
args: {
posts: postsArray,
},
})

export const generatePostTxnInput = (post: Post) => ({
projectId: projectIdPost,
contractAddress: addresses.postGateway.nova,
chainId: 42170,
functionSignature:
'post((address signer, (uint256 rid, uint256 timestamp, uint8 msgType, bytes msgBody) message, uint16 hashType, bytes32 hash, uint16 sigType, bytes sig) post)',
args: {
post: post,
},
})

export const generateIdRegistryInput = (register: Register) => ({
projectId: projectIdRegistry,
contractAddress: addresses.idRegistry.optimism,
chainId: 10,
functionSignature:
'registerFor(address to, address recovery, uint256 deadline, bytes sig)',
args: {
to: register.to,
recovery: register.recovery,
deadline: register.deadline,
sig: register.sig,
},
})

export const syndicateClientPost = new SyndicateClient({ token: process.env.SYNDICATE_POST_API_KEY as string })
export const syndicateClientIdRegistry = new SyndicateClient({ token: process.env.SYNDICATE_ID_API_KEY as string })
Loading

0 comments on commit 31c62c6

Please sign in to comment.