feat: smart contract setTokenVerified calls through ethers (#272)
* feat: add scripts to create lambda layers * chore: deploy the new version of the contract to mumbai. * feat: update environment variables used in the serverless config. * feat: add JSON_RPC env var. * feat: add deploy:dev command. * feat: functional deployment script, configuration changes. * feat: update config and the deploy script. * docs: add the serverless stack diagram * feat: move the ABI to the lib dir, update the build handler + some minor changes on the config files. * feat: add ethers to the library, send transactions through the contract instance. * fix: make the ethers transaction signing work, update handlers accordingly, customize prisma logs, update the config files to match the changes. * feat: remove logs, log specific errors for environment variables, update hardhat config. * feat: add support for the --stage flag in the deploy script. --------- Co-authored-by: root <root@LAPTOP-UJU1VIVI> Co-authored-by: Nima Rasooli <nimarasooli1@gmail.com>
This commit is contained in:
parent
94313c0300
commit
bbe73f4d73
|
|
@ -36,6 +36,7 @@
|
||||||
"@prisma/client": "^4.13.0",
|
"@prisma/client": "^4.13.0",
|
||||||
"@types/node": "^18.15.11",
|
"@types/node": "^18.15.11",
|
||||||
"aws-sdk": "^2.1342.0",
|
"aws-sdk": "^2.1342.0",
|
||||||
|
"ethers": "5.7.2",
|
||||||
"prisma": "^4.13.0",
|
"prisma": "^4.13.0",
|
||||||
"ts-node": "^10.9.1",
|
"ts-node": "^10.9.1",
|
||||||
"typescript": "^5.0.4",
|
"typescript": "^5.0.4",
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,34 @@ source .env
|
||||||
|
|
||||||
echo "${bold}Starting the deployment process${normal}"
|
echo "${bold}Starting the deployment process${normal}"
|
||||||
|
|
||||||
|
# Default value for the stage variable
|
||||||
|
stage="dev"
|
||||||
|
|
||||||
|
# Parse command line options using getopts
|
||||||
|
while [[ $# -gt 0 ]]; do
|
||||||
|
key="$1"
|
||||||
|
|
||||||
|
case $key in
|
||||||
|
--stage)
|
||||||
|
shift
|
||||||
|
stage="$1"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
# Ignore unknown options or arguments
|
||||||
|
;;
|
||||||
|
esac
|
||||||
|
|
||||||
|
shift
|
||||||
|
done
|
||||||
|
|
||||||
|
# Check if the stage variable has a non-empty value
|
||||||
|
if [ -n "$stage" ]; then
|
||||||
|
echo "Passed stage value: $stage"
|
||||||
|
else
|
||||||
|
echo "Stage flag not provided or value not specified."
|
||||||
|
echo "Will proceed with the default value: dev"
|
||||||
|
fi
|
||||||
|
|
||||||
echo "${bold}Installing dependencies via Yarn${normal}"
|
echo "${bold}Installing dependencies via Yarn${normal}"
|
||||||
|
|
||||||
yarn
|
yarn
|
||||||
|
|
@ -48,22 +76,25 @@ if [[ -z "${AWS_SECRET_ACCESS_KEY}" ]]; then
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "${bold}Copying the Prisma schema file to function directories${normal}"
|
echo "${bold}Copying the Prisma schema file to function directories${normal}"
|
||||||
cp prisma/schema.prisma dist/serverless/src/functions/builds/
|
cp prisma/schema.prisma dist/src/functions/builds/
|
||||||
cp prisma/schema.prisma dist/serverless/src/functions/mints/
|
cp prisma/schema.prisma dist/src/functions/mints/
|
||||||
|
|
||||||
echo "${bold}Running the build command${normal}"
|
echo "${bold}Running the build command${normal}"
|
||||||
yarn build
|
yarn build
|
||||||
|
|
||||||
echo "${bold}Copying the rhel openssl engine to dist/${normal}"
|
echo "${bold}Copying the rhel openssl engine to dist/${normal}"
|
||||||
cp node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node dist/serverless/src/functions/mints
|
cp node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node dist/src/functions/mints
|
||||||
cp node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node dist/serverless/src/functions/builds
|
cp node_modules/.prisma/client/libquery_engine-rhel-openssl-1.0.x.so.node dist/src/functions/builds
|
||||||
|
|
||||||
echo "${bold}Copying the .env file to dist/${normal}"
|
echo "${bold}Copying the .env file to dist/${normal}"
|
||||||
cp .env src/
|
cp .env src/
|
||||||
|
|
||||||
|
echo "${bold}Copying the FleekERC721.json file to dist/serverless/src/libs${normal}"
|
||||||
|
cp src/libs/FleekERC721.json dist/src/libs/
|
||||||
|
|
||||||
echo "${bold}Copying the Prisma schema file to function directories${normal}"
|
echo "${bold}Copying the Prisma schema file to function directories${normal}"
|
||||||
cp prisma/schema.prisma dist/serverless/src/functions/builds/
|
cp prisma/schema.prisma dist/src/functions/builds/
|
||||||
cp prisma/schema.prisma dist/serverless/src/functions/mints/
|
cp prisma/schema.prisma dist/src/functions/mints/
|
||||||
|
|
||||||
echo "${bold}Generating Prisma Client${normal}"
|
echo "${bold}Generating Prisma Client${normal}"
|
||||||
yarn prisma:generate
|
yarn prisma:generate
|
||||||
|
|
@ -74,7 +105,7 @@ echo "${bold}Creating layer zip files${normal}"
|
||||||
/bin/bash ./scripts/prepare-node-modules-lambda-layer.sh
|
/bin/bash ./scripts/prepare-node-modules-lambda-layer.sh
|
||||||
|
|
||||||
echo "${bold}Deploying to AWS lambda${normal}"
|
echo "${bold}Deploying to AWS lambda${normal}"
|
||||||
yarn sls deploy --stage dev --verbose
|
yarn sls deploy --stage "$stage" --verbose
|
||||||
|
|
||||||
# step 0 -> run yarn
|
# step 0 -> run yarn
|
||||||
# step 1 -> take params (env variables)
|
# step 1 -> take params (env variables)
|
||||||
|
|
|
||||||
|
|
@ -44,17 +44,10 @@ custom:
|
||||||
concurrency: 10
|
concurrency: 10
|
||||||
|
|
||||||
functions:
|
functions:
|
||||||
submitAppInfo:
|
|
||||||
handler: src/functions/apps/handler.submitAppInfo
|
|
||||||
events:
|
|
||||||
- http:
|
|
||||||
path: app
|
|
||||||
method: post
|
|
||||||
cors: true
|
|
||||||
|
|
||||||
submitBuildInfo:
|
submitBuildInfo:
|
||||||
# Deployment:
|
# Deployment:
|
||||||
handler: ./dist/serverless/src/functions/builds/handler.submitBuildInfo # TODO This will not work, need to change to nfa-serverless/dist/serverless/src/functions/builds/handler.submitBuildInfo
|
handler: ./dist/src/functions/builds/handler.submitBuildInfo # TODO This will not work, need to change to nfa-serverless/dist/serverless/src/functions/builds/handler.submitBuildInfo
|
||||||
# Local development:
|
# Local development:
|
||||||
# handler: ./src/functions/builds/handler.submitBuildInfo
|
# handler: ./src/functions/builds/handler.submitBuildInfo
|
||||||
events:
|
events:
|
||||||
|
|
@ -75,7 +68,7 @@ functions:
|
||||||
|
|
||||||
submitMintInfo:
|
submitMintInfo:
|
||||||
# Deployment:
|
# Deployment:
|
||||||
handler: ./dist/serverless/src/functions/mints/handler.submitMintInfo # TODO This will not work, need to change to nfa-serverless/dist/serverless/src/functions/mints/handler.submitMintInfo
|
handler: ./dist/src/functions/mints/handler.submitMintInfo # TODO This will not work, need to change to nfa-serverless/dist/serverless/src/functions/mints/handler.submitMintInfo
|
||||||
# Local development:
|
# Local development:
|
||||||
# handler: ./src/functions/mints/handler.submitMintInfo
|
# handler: ./src/functions/mints/handler.submitMintInfo
|
||||||
events:
|
events:
|
||||||
|
|
@ -100,4 +93,12 @@ functions:
|
||||||
- http:
|
- http:
|
||||||
path: verifyApp
|
path: verifyApp
|
||||||
method: post
|
method: post
|
||||||
cors: true
|
cors: true
|
||||||
|
|
||||||
|
submitAppInfo:
|
||||||
|
handler: src/functions/apps/handler.submitAppInfo
|
||||||
|
events:
|
||||||
|
- http:
|
||||||
|
path: app
|
||||||
|
method: post
|
||||||
|
cors: true
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,8 @@
|
||||||
import { APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda';
|
import { APIGatewayProxyResult, APIGatewayEvent } from 'aws-lambda';
|
||||||
import { formatJSONResponse } from '@libs/api-gateway';
|
import { formatJSONResponse } from '@libs/api-gateway';
|
||||||
|
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { prisma } from '@libs/prisma';
|
import { prisma } from '@libs/prisma';
|
||||||
import { account, nfaContract } from '@libs/nfa-contract';
|
import { contractInstance } from '@libs/nfa-contract';
|
||||||
|
|
||||||
export const submitBuildInfo = async (
|
export const submitBuildInfo = async (
|
||||||
event: APIGatewayEvent
|
event: APIGatewayEvent
|
||||||
|
|
@ -26,6 +25,7 @@ export const submitBuildInfo = async (
|
||||||
commitHash: data.commitHash,
|
commitHash: data.commitHash,
|
||||||
ipfsHash: data.ipfsHash,
|
ipfsHash: data.ipfsHash,
|
||||||
domain: data.domain,
|
domain: data.domain,
|
||||||
|
verificationTransactionHash: 'Not verified.',
|
||||||
};
|
};
|
||||||
console.log(buildInfo);
|
console.log(buildInfo);
|
||||||
|
|
||||||
|
|
@ -65,18 +65,13 @@ export const submitBuildInfo = async (
|
||||||
});
|
});
|
||||||
|
|
||||||
if (mintRecord.length > 0) {
|
if (mintRecord.length > 0) {
|
||||||
// Trigger verification
|
|
||||||
|
|
||||||
// Mark the token as verified in the contract
|
// Mark the token as verified in the contract
|
||||||
// call the `setTokenVerified` method
|
// call the `setTokenVerified` method
|
||||||
await nfaContract.methods
|
const transaction = await contractInstance.setTokenVerified(
|
||||||
.setTokenVerified(mintRecord[0].tokenId, true)
|
mintRecord[0].tokenId,
|
||||||
.send({
|
true
|
||||||
from: account.address,
|
);
|
||||||
gas: '1000000',
|
buildInfo.verificationTransactionHash = transaction.hash;
|
||||||
})
|
|
||||||
.catch(console.error);
|
|
||||||
|
|
||||||
// Update the database record in the tokens collection
|
// Update the database record in the tokens collection
|
||||||
await prisma.tokens.updateMany({
|
await prisma.tokens.updateMany({
|
||||||
where: {
|
where: {
|
||||||
|
|
|
||||||
|
|
@ -4,11 +4,9 @@ import {
|
||||||
///APIGatewayEventRequestContext,
|
///APIGatewayEventRequestContext,
|
||||||
} from 'aws-lambda';
|
} from 'aws-lambda';
|
||||||
import { formatJSONResponse } from '@libs/api-gateway';
|
import { formatJSONResponse } from '@libs/api-gateway';
|
||||||
|
|
||||||
import { v4 } from 'uuid';
|
import { v4 } from 'uuid';
|
||||||
import { initPrisma, prisma } from '@libs/prisma';
|
import { initPrisma, prisma } from '@libs/prisma';
|
||||||
import { account, nfaContract, web3 } from '@libs/nfa-contract';
|
import { contractInstance, web3 } from '@libs/nfa-contract';
|
||||||
|
|
||||||
export const submitMintInfo = async (
|
export const submitMintInfo = async (
|
||||||
event: APIGatewayEvent
|
event: APIGatewayEvent
|
||||||
///context: APIGatewayEventRequestContext
|
///context: APIGatewayEventRequestContext
|
||||||
|
|
@ -20,6 +18,7 @@ export const submitMintInfo = async (
|
||||||
message: 'Required parameters were not passed.',
|
message: 'Required parameters were not passed.',
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
const id = v4();
|
const id = v4();
|
||||||
/**if (!verifyAlchemySig(event.headers.xalchemywork)) {
|
/**if (!verifyAlchemySig(event.headers.xalchemywork)) {
|
||||||
throw new Error('Invalid sig');
|
throw new Error('Invalid sig');
|
||||||
|
|
@ -128,6 +127,7 @@ export const submitMintInfo = async (
|
||||||
owner: decodedLogs.owner,
|
owner: decodedLogs.owner,
|
||||||
ipfsHash: decodedLogs.ipfsHash,
|
ipfsHash: decodedLogs.ipfsHash,
|
||||||
domain: decodedLogs.externalURL,
|
domain: decodedLogs.externalURL,
|
||||||
|
verificationTransactionHash: 'Not verified'
|
||||||
};
|
};
|
||||||
|
|
||||||
initPrisma();
|
initPrisma();
|
||||||
|
|
@ -148,13 +148,13 @@ export const submitMintInfo = async (
|
||||||
if (build.length > 0) {
|
if (build.length > 0) {
|
||||||
// Mark the token as verified in the contract
|
// Mark the token as verified in the contract
|
||||||
try {
|
try {
|
||||||
|
// what if the token has been burned?
|
||||||
// call the `setTokenVerified` method
|
// call the `setTokenVerified` method
|
||||||
await nfaContract.methods
|
const transaction = await contractInstance.setTokenVerified(
|
||||||
.setTokenVerified(mintInfo.tokenId, true)
|
mintInfo.tokenId,
|
||||||
.send({
|
true
|
||||||
from: account.address,
|
);
|
||||||
gas: '1000000',
|
mintInfo.verificationTransactionHash = transaction.hash;
|
||||||
});
|
|
||||||
verified = true;
|
verified = true;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
// catch transaction error
|
// catch transaction error
|
||||||
|
|
|
||||||
|
|
@ -1,17 +1,27 @@
|
||||||
|
import { Contract, Wallet, ethers } from 'ethers';
|
||||||
|
import * as abiFile from '@libs/FleekERC721.json';
|
||||||
import Web3 from 'web3';
|
import Web3 from 'web3';
|
||||||
import * as abiFile from './FleekERC721.json';
|
|
||||||
|
|
||||||
if (
|
if (process.env.PRIVATE_KEY === undefined) {
|
||||||
process.env.PRIVATE_KEY === undefined ||
|
throw Error('Private Key environment variable not set.');
|
||||||
process.env.JSON_RPC === undefined
|
|
||||||
) {
|
|
||||||
throw Error('Private key or the JSON RPC environment variable not set.');
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const contract_address = abiFile.address;
|
if (process.env.JSON_RPC === undefined) {
|
||||||
export const abi = abiFile.abi as any;
|
throw Error('JSON RPC environment variable not set.');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (process.env.CONTRACT_ADDRESS === undefined) {
|
||||||
|
throw Error('Contract Address environment variable not set.');
|
||||||
|
}
|
||||||
|
|
||||||
export const web3 = new Web3(process.env.JSON_RPC);
|
export const web3 = new Web3(process.env.JSON_RPC);
|
||||||
export const account = web3.eth.accounts.wallet.add(process.env.PRIVATE_KEY);
|
const CONTRACT_ADDRESS = process.env.CONTRACT_ADDRESS;
|
||||||
web3.eth.setProvider(Web3.givenProvider);
|
// RPC loaded from env file previously
|
||||||
export const nfaContract = new web3.eth.Contract(abi, contract_address);
|
const provider = new ethers.providers.JsonRpcProvider(process.env.JSON_RPC);
|
||||||
|
// account key loaded from env file previously
|
||||||
|
export const signer = new Wallet(process.env.PRIVATE_KEY, provider);
|
||||||
|
export const contractInstance = new Contract(
|
||||||
|
CONTRACT_ADDRESS,
|
||||||
|
abiFile.abi,
|
||||||
|
signer
|
||||||
|
);
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
import { PrismaClient } from '@prisma/client';
|
import { PrismaClient } from '@prisma/client';
|
||||||
|
|
||||||
export const prisma = new PrismaClient();
|
export const prisma = new PrismaClient({log: ['warn', 'error']});
|
||||||
|
|
||||||
export async function initPrisma() {
|
export async function initPrisma() {
|
||||||
// Connect the client
|
// Connect the client
|
||||||
|
|
|
||||||
3117
serverless/yarn.lock
3117
serverless/yarn.lock
File diff suppressed because it is too large
Load Diff
Loading…
Reference in New Issue