Hardhat-Ethers forking test - testing

I want to write a test that simultaniously works with already deployed contracts from the mainnet, change it state in fork and can deploy its own contracts in the same fork. This is my test:
it("Deploy check", async function () {
const provider = new ethers.providers.AlchemyProvider("homestead", process.env.ALCHEMY_API_KEY)
const [Alice] = await ethers.getSigners()
const WETH9 = await new ethers.Contract(ETHEREUM.WETH9.address, WETH9ABI, provider)
const txGetWETH = await WETH9.connect(Alice).deposit({value: getBigNumber(1e18)})
const balance = await WETH9.connect(provider).balanceOf(Alice.address)).toString();
expect(balance).equals(1e18)
})
But the result balance is 0 (
My default hardhat network configuration:
hardhat: {
forking: {
enabled: process.env.FORKING === "true",
url: `https://eth-mainnet.alchemyapi.io/v2/${process.env.ALCHEMY_API_KEY}`,
},
live: false,
saveDeployments: true,
tags: ["test", "local"],
},
Could please anybody explain - what I do wrong? I want balance to be changed in my fork
Thank you!

OK, I've changed 'enabled: process.env.FORKING === "true"' to 'enabled: true'
and WETH9 provider from provider to Alice.
And it works now !
Closed )

Related

How to call Openbrush contract from Front-end app

I implement smart contracts with ink!, substrate's WASM smart contract implementation language.
At that time, I decided to use the openbrush library. openbrush is like openzeppelin in EVM.
The smart contract was easy to implement according to the official website. [https://docs.openbrush.io/]
But I couldn't figure out how to call it from the front end.
I was able to solve it by looking at Telegram, but I will write this in the hope that it will help others.
A function defined in openbrush is declared like this:
psp34::transfer (to: TransferInput1, id: TransferInput2, data: TransferInput3)
psp34::ownerOf (id: OwnerOfInput1): Option<AccountId>
Below is a sample code that calls the above two contract functions.
const wsProvider = new WsProvider(blockchainUrl);
const api = await ApiPromise.create({ provider: wsProvider });
const contract = new ContractPromise(api, psp_abi, PSP_ADDRESS);
setApi(api);
const { gasConsumed, result, output } = await contract.query['psp34::ownerOf'](
actingAddress,
{ value: 0, gasLimit: -1 },
NFT_ID
);
const { web3FromSource } = await import("#polkadot/extension-dapp");
const wsProvider = new WsProvider(blockchainUrl);
const api = await ApiPromise.create({ provider: wsProvider });
setApi(api);
const contract = new ContractPromise(api, psp_abi, PSP_ADDRESS);
const performingAccount = accounts[0];
const injector = await web3FromSource(performingAccount.meta.source);
const flip = await contract.tx['psp34::transfer'](
{ value: 0, gasLimit: gasLimit },
"ajYMsCKsEAhEvHpeA4XqsfiA9v1CdzZPrCfS6pEfeGHW9j8",
NFT_ID,
Null
);
if (injector !== undefined) {
const unsub = await flip.signAndSend(
actingAddress,
{ signer: injector.signer },
({ events = [], status }) => {
-- snip --

Problems with deploying first smart contracts

Good day everyone!
I'm trying to deploy the first smart contracts according to the helloWorld manuals, but I'm getting an error please see the snippet. Tell me, please, what can be done about this? Tried lot of way to fix it but failed.
Thanks in advance!
import { Command } from ""commander"";
import prompts, { PromptObject } from ""prompts"";
import { isNumeric, Migration } from ""./utils"";
const program = new Command();
const migration = new Migration();
async function main() {
const promptsData: PromptObject[] = [];
program
.allowUnknownOption()
.option(""-kn, --key_number <key_number>"", ""Public key number"")
.option(
""-b, --balance <balance>"",
""Initial balance in EVERs (will send from Giver)"",
);
program.parse(process.argv);
const options = program.opts();
if (!options.key_number) {
promptsData.push({
type: ""text"",
name: ""keyNumber"",
message: ""Public key number"",
validate: value => (isNumeric(value) ? true : ""Invalid number""),
});
}
if (!options.balance) {
promptsData.push({
type: ""text"",
name: ""balance"",
message: ""Initial balance (will send from Giver)"",
validate: value => (isNumeric(value) ? true : ""Invalid number""),
});
}
const response = await prompts(promptsData);
const keyNumber = +(options.key_number || response.keyNumber);
const balance = +(options.balance || response.balance);
const signer = (await locklift.keystore.getSigner(keyNumber.toString()))!;
let accountsFactory = locklift.factory.getAccountsFactory(""Account"");
const { account: Account } = await accountsFactory.deployNewAccount({
publicKey: signer.publicKey,
initParams: {
_randomNonce: locklift.utils.getRandomNonce(),
},
constructorParams: {},
value: locklift.utils.toNano(balance),
});
migration.store(Account, ""account"");
console.log(`Account deployed at: ${Account.address}`);
}
main()
.then(() => process.exit(0))
.catch(e => {
console.log(e);
process.exit(1);
});"
Crashes on an attempt to collect Account contract assembly artefacts
There is no such thing in the build folder!

cypress-keycloak-commands using on keycloak login

I try to use cypress-keycloak-commands in my tests but always get this error:
I did everything accorig to this docu: https://www.npmjs.com/package/cypress-keycloak-commands
I don't understand how the code should know where to fill in the username an password. This is my code for the login:
it('Login', () => {
cy.visit(Cypress.env('GBS_URL'))
cy.kcLogout();
cy.kcLogin("user");
cy.visit("/"); })
What is the probleme here? I changed the user.json to my setings, added the env: { ... } to the json abd installed the package. Also added:import "cypress-keycloak-commands"; in the commands.js file.
The error comes from the keycloak library, and it's expecting to find a <form> element, but not finding it.
This is the piece of code where the error occurs.
const authBaseUrl = Cypress.env("auth_base_url");
const realm = Cypress.env("auth_realm");
const client_id = Cypress.env("auth_client_id");
cy.request({
url: `${authBaseUrl}/realms/${realm}/protocol/openid-connect/auth`,
followRedirect: false,
qs: {
scope: "openid",
response_type: "code",
approval_prompt: "auto",
redirect_uri: Cypress.config("baseUrl"),
client_id
}
})
.then(response => {
const html = document.createElement("html");
html.innerHTML = response.body;
const form = html.getElementsByTagName("form")[0];
const url = form.action;
The form should be part of the response.body, but since it's not there the request must be failing.
Check what you have in Cypress.env("auth_base_url"), Cypress.env("auth_realm") and Cypress.env("auth_client_id")
If you added them to cypress.json they would be similar to this
Ref Setup Keycloak configuration
Setup the Keycloak configuration in cypress.json configuration file:
{
"env": {
"auth_base_url": "https://auth.server/auth",
"auth_realm": "my_realm",
"auth_client_id": "my_client_id"
}
}

Testcafe not working for Nuxt/Vue Amplify/Cognito calls. RangeError: Maximum call stack size exceeded

I have been trying out Testcafe for our Nuxt application E2E tests as I understood it has good selectors with VueJS and its working great except for the parts where a call is made to cognito via amplify for user login/signup. It might be a testcafe and amplify issue rather than the frontend framework issue as the Login/Signup works absolutely fine. Also tried replacing the Cognito calls with normal REST api calls and it works fine too. Also tried it with Cypress and they work fine but Testcafe has better coverage in terms of cross browser testing so maybe a better option. Do you know if how I can fix this error or its better to look into different frameworks? Will try to share share my code in the best way possible as I cannot share my repo as its for my company. And will be happy to answer with more code or clarifications if required. Thanks and find the code below:
My submit function:
async submit() {
this.$v.$touch();
if (this.$v.$invalid) return;
this.disabled = true;
try {
await this.registerUser({
username: this.email,
password: this.newPassword,
attributes: {
given_name: this.firstname,
family_name: this.lastname,
email: this.email,
'custom:isPerson': 'true',
'custom:dataPrivacy': 'true'
}
});
this.$router.push(this.appendLocalization('/user/confirmuser'));
this.disabled = false;
} catch (error) {
this.$log.error('Could not register user', error);
this.disabled = false;
}
The amplify function:
import Auth from '#aws-amplify/auth';
import Amplify from '#aws-amplify/core';
Amplify.configure({
Auth: {
userPoolId: process.env.userPoolId,
userPoolWebClientId: process.env.userPoolWebClientId,
region: process.env.region
}
});
export const state = () => {
return {
session: {},
user: {}
};
};
export const mutations = {
setUser: (state, user) => {
state.user = { ...user };
state.session = state.user.signInUserSession;
}
};
registerUser: ({ commit }, credentials) =>
new Promise((resolve, reject) => {
Auth.signUp({
username: credentials.username,
password: credentials.password,
attributes: credentials.attributes
})
.then((user) => {
commit('setUser', user);
resolve(user);
})
.catch(reject);
}),
My Testcafe code:
import { Selector, ClientFunction } from 'testcafe';
fixture`Signup Page`.page`http://localhost:3000/de/user/signup`;
const email = Selector('input').withAttribute('name', 'email');
const password = Selector('input').withAttribute('name', 'password');
const checkbox = Selector('input').withAttribute('type', 'checkbox');
const button = Selector('button').withAttribute('name', 'submit');
const getLocation = ClientFunction(() => document.location.href);
test('Test successful signup', async (t) => {
const validemail =
'WebFunctionalTest' + new Date().getTime() + '#something.com';
const validpassword = 'password';
await t
.typeText(email, validemail)
.typeText(password, validpassword)
await t.click(button).debug();
await t.expect(getLocation()).contains('userconfirm');
});
Signup Error:
RangeError: Maximum call stack size exceeded
at c (hammerhead.js:16)
at i (hammerhead.js:16)
at value (hammerhead.js:6)
at _traverse (commons.app.js:12575)
at _traverse (commons.app.js:12575)
at _traverse (commons.app.js:12575)
at _traverse (commons.app.js:12575)
at _traverse (commons.app.js:12575)
at _traverse (commons.app.js:12575)
at _traverse (commons.app.js:12575)
P.S: I can see that Testcafe is making the cognito call and is getting a proper response in network tab but somehow not handling it in the code. I thought Testcafe should behave like a normal user testing like click the button and wait for the whole sequence to finish i.e successful page transition but somehow it's not.
I have spent quite sometime trying to figure this out but couldnt so posting it elaborately here, any help will be very appreciated. Thanks in advance.

Relay subscriptions not working with react-native

I'm using Express Graphql server with react native and Relay. My device does connects to the subscription but it does not subscribe to it. Here's my index.js on the server
const subscriptionServer = SubscriptionServer.create(
{
execute,
subscribe,
schema,
onOperation: (message, params, webSocket) => {
console.log(params)
return params;
},
onConnect: () => {
// My device does connects
console.log("client connected")
}
},
{
server,
path: '/subscriptions'
},
);
app.use('/graphql', graphqlHTTP({
schema,
graphiql: true
}));
app.use('/graphiql', graphiqlExpress({
endpointURL: '/graphql',
subscriptionsEndpoint: `ws://127.0.0.1:8080/subscriptions`
}));
server.listen(PORT, ()=> {
console.log("Groceries running on port " + PORT)
console.log(
`subscriptions is now running on ws://localhost:${PORT}/subscriptions'}`
);
});
The resolver for subscription on the server, it was quite troublesome to figure out since everyone is using executable schema from apolloGraphql.
export default {
type: OrderEdges,
args: {
ShopId: {type: GraphQLID},
},
subscribe: withFilter(() => pubsub.asyncIterator('orderConfirmed'), (payload, variables) => {
console.log(payload)
console.log(variables)
return payload.orderConfirmed.node.ShopId == variables.ShopId;
}),
}
Now the react-native client. My subscription setup with relay environment.
const setupSubscriptions = (config, variables, cacheConfig, observer) => {
const query = config.text; //does console logs the query
const subscriptionClient = new SubscriptionClient(`ws://192.168.0.100:8080/subscriptions`, {reconnect:true});
subscriptionClient.request({query, variables}, (err, result) => {
console.log(err) // doesn't get call inside the request method
observer.onNext(data:result)
})
}
My subscription method,
export default function() {
const variables = {
ShopId: shop.getShop()[0].id
}
requestSubscription(
environment,
{
subscription,
variables,
onCompleted: (res, err) => {
console.log(res)
console.log(err)
},
updater: (store) => {...},
onError: error => console.error(error),
onNext: (response) => {console.log(response)}
});
}
the component where I'm calling to subscribe,
import subscription from '../../GraphQLQueries/subscriptions/orderConfirmed';
class OrdersBox extends React.Component {
constructor(props) {
super(props);
}
componentDidMount() {
//initializing subscription
orderSubscriptions();
}
When the device starts the app, my device is connected to the web socket as I can see the console.log statement inside the onConnect method in SubscriptionServer. But when the payload is published after a mutation, the subscribe method doesn't get called. I can't seem to figure out what I'm doing wrong. Maybe it's some react-native specific config that I'm missing cuz everything seems to work fine when I test it on graphiql.
I can't find any example of react-native and relay subscriptions used with express graphql.
note: Everything is working when I use subscription with graphiql. But not with react-native and relay.
Thanks in advance guys
....
I wasn't returning the subscriptionClient.request method. Adding a return statement solved the problem. You don't have to return when using subscribe method in subscriptions-transport-ws#0.8.3. But version 0.9.1 replaces the subscribe function with request which does require it to return.
try:
function setupSubscription(config, variables, cacheConfig, observer) {
const query = config.text;
const subscriptionClient = new SubscriptionClient(websocketURL, {
reconnect: true
});
const client = subscriptionClient.request({ query, variables }).subscribe({
next: result => {
observer.onNext({ data: result.data });
},
complete: () => {
observer.onCompleted();
},
error: error => {
observer.onError(error);
}
});
return {
dispose: client.unsubscribe
};
}
subscriptions-transport-ws#0.9.1