-
Notifications
You must be signed in to change notification settings - Fork 3
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
first pass at syndicate integration #549
base: main
Are you sure you want to change the base?
Changes from 8 commits
703aafc
fcb1c11
55a14b2
8a43298
13d200a
0883ee3
aecd49a
84f8181
87a0e26
063a335
b5e0ef7
dd8316d
4dbf651
5813ab2
6632a9a
f80ea11
469a162
34391e7
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -27,6 +27,7 @@ yarn-error.log* | |
# local env files | ||
.env*.local | ||
.env | ||
.env.* | ||
|
||
# vercel | ||
.vercel | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,41 +1,48 @@ | ||
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' | ||
import { syndicate } from '@/config/syndicateClient' | ||
import { addresses } from 'scrypt' | ||
import { waitUntilTx } from '@/lib' | ||
|
||
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 projectId = process.env.SYNDICATE_PROJECT_ID_POSTGATEWAY | ||
|
||
const tx = await postGateway.post(post) | ||
if (!projectId) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. lets move as much of this as possible into the syndicate config. did a lil gist brainstorming here https://gist.github.com/0xTranqui/3a00d776f4065db0c77106685f941d24 |
||
throw new Error( | ||
'SYNDICATE_PROJECT_ID_POSTGATEWAY is not defined in environment variables.', | ||
) | ||
} | ||
|
||
await novaPubClient.waitForTransactionReceipt({ | ||
hash: tx.hash as Hex, | ||
const postTx = await syndicate.transact.sendTransaction({ | ||
projectId: projectId, | ||
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, | ||
}, | ||
}) | ||
|
||
return new Response(JSON.stringify({ success: true, hash: tx.hash }), { | ||
status: 200, | ||
headers: { 'Content-Type': 'application/json' }, | ||
console.log({ postTx }) | ||
|
||
// Use the waitUntilTx function to wait for the transaction to be processed | ||
const successfulTxHash = await waitUntilTx({ | ||
projectID: projectId, | ||
txID: postTx.transactionId, | ||
}) | ||
|
||
console.log({ successfulTxHash }) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. we should prob remove most/all of these console logs before merging? what u think |
||
|
||
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 | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
import { SyndicateClient } from '@syndicateio/syndicate-node' | ||
|
||
export const syndicate = new SyndicateClient({ | ||
token: () => { | ||
const apiKey = process.env.SYNDICATE_API_KEY | ||
if (typeof apiKey === 'undefined') { | ||
throw new Error( | ||
'SYNDICATE_API_KEY is not defined in environment variables.', | ||
) | ||
} | ||
return apiKey | ||
}, | ||
}) |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -21,6 +21,98 @@ type User = { | |
sig: string | ||
} | ||
|
||
export interface TransactionAttempt { | ||
block: number | ||
blockCreatedAt: string | ||
chainId: number | ||
createdAt: string | ||
hash: string | ||
nonce: number | ||
reverted: boolean | ||
signedTxn: string | ||
status: string | ||
transactionId: string | ||
updatedAt: string | ||
walletAddress: string | ||
} | ||
|
||
export interface SyndicateApiResponse { | ||
chainId: number | ||
contractAddress: string | ||
createdAt: string | ||
data: string | ||
decodedData: object | ||
functionSignature: string | ||
invalid: boolean | ||
projectId: string | ||
transactionAttempts: TransactionAttempt[] | ||
transactionId: string | ||
updatedAt: string | ||
value: string | ||
} | ||
|
||
export interface WaitUntilTxOptions { | ||
projectID: string | ||
txID: string | ||
maxAttempts?: number | ||
every?: number | ||
} | ||
|
||
export const getTransactionRequest = async ({ | ||
projectID, | ||
txID, | ||
}: Pick<WaitUntilTxOptions, 'projectID' | 'txID'>) => { | ||
const response = await fetch( | ||
`https://api.syndicate.io/wallet/project/${projectID}/request/${txID}`, | ||
{ | ||
method: 'GET', | ||
headers: { Authorization: `Bearer ${process.env.SYNDICATE_API_KEY}` }, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. better dx to accept api key as a prop? instead of loading in from env here? like we do for w3supload down below? |
||
}, | ||
) | ||
if (!response.ok) { | ||
throw new Error(`Failed to get transaction request: ${response.statusText}`) | ||
} | ||
return response.json() | ||
} | ||
|
||
export async function waitUntilTx({ | ||
projectID, | ||
txID, | ||
maxAttempts = 20, | ||
every = 1000, | ||
}: WaitUntilTxOptions) { | ||
let currAttempts = 0 | ||
let transactionHash = null | ||
|
||
while (!transactionHash) { | ||
await new Promise((resolve) => setTimeout(resolve, every)) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I feel like the delay is better suited for coming at the end of the loop, and only if its necssary (ie there will be another loop cuz was uncessful) like we do in this similar function that we use to wait for appearnace in ponder db? https://github.com/1ifeworld/river/blob/main/apps/site/lib/getTxnInclusion.ts |
||
|
||
if (currAttempts >= maxAttempts) { | ||
throw new Error('Max attempts reached') | ||
} | ||
|
||
const txAttempts = (await getTransactionRequest({ projectID, txID })) | ||
?.transactionAttempts | ||
|
||
console.log({ txAttempts }) | ||
|
||
if ( | ||
txAttempts && | ||
txAttempts.length > 0 && | ||
txAttempts[txAttempts.length - 1].status === 'PENDING' && | ||
!txAttempts[txAttempts.length - 1].reverted | ||
) { | ||
transactionHash = txAttempts[txAttempts.length - 1].hash | ||
console.log(transactionHash) | ||
break | ||
} | ||
|
||
currAttempts += 1 | ||
} | ||
|
||
return transactionHash | ||
} | ||
|
||
/* API ROUTES */ | ||
|
||
// This is in to help with serialization of bigints during json stringify | ||
|
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we get rid of this added Hex? not seeing any other changes to Delta so should be unncessary? just in terms of keeping the commit trail on delta clean