chore: tidy market setup scripts (#2657)
This commit is contained in:
parent
c1ebda9274
commit
c533c584da
1
libs/cypress/src/lib/capsule/contants.ts
Normal file
1
libs/cypress/src/lib/capsule/contants.ts
Normal file
@ -0,0 +1 @@
|
|||||||
|
export const ASSET_ID_FOR_MARKET = 'fUSDC';
|
@ -1,9 +1,8 @@
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { gql } from 'graphql-request';
|
|
||||||
import { determineId } from '../utils';
|
import { determineId } from '../utils';
|
||||||
import { requestGQL, setEndpoints } from './request';
|
import { setGraphQLEndpoint } from './request';
|
||||||
import { vote } from './vote';
|
import { vote } from './vote';
|
||||||
import { setupEthereumAccount } from './ethereum-setup';
|
import { stakeForVegaPublicKey } from './ethereum-setup';
|
||||||
import { faucetAsset } from './faucet-asset';
|
import { faucetAsset } from './faucet-asset';
|
||||||
import {
|
import {
|
||||||
proposeMarket,
|
proposeMarket,
|
||||||
@ -11,6 +10,10 @@ import {
|
|||||||
waitForProposal,
|
waitForProposal,
|
||||||
} from './propose-market';
|
} from './propose-market';
|
||||||
import { createLog } from './logging';
|
import { createLog } from './logging';
|
||||||
|
import { getMarkets } from './get-markets';
|
||||||
|
import { createWalletClient } from './wallet-client';
|
||||||
|
import { createEthereumWallet } from './ethereum-wallet';
|
||||||
|
import { ASSET_ID_FOR_MARKET } from './contants';
|
||||||
|
|
||||||
const log = createLog('create-market');
|
const log = createLog('create-market');
|
||||||
|
|
||||||
@ -23,8 +26,10 @@ export async function createMarket(cfg: {
|
|||||||
vegaUrl: string;
|
vegaUrl: string;
|
||||||
faucetUrl: string;
|
faucetUrl: string;
|
||||||
}) {
|
}) {
|
||||||
// set and store request endpoints
|
// setup wallet client and graphql clients
|
||||||
setEndpoints(cfg.vegaWalletUrl, cfg.vegaUrl);
|
setGraphQLEndpoint(cfg.vegaUrl);
|
||||||
|
createWalletClient(cfg.vegaWalletUrl, cfg.token);
|
||||||
|
createEthereumWallet(cfg.ethWalletMnemonic, cfg.ethereumProviderUrl);
|
||||||
|
|
||||||
const markets = await getMarkets();
|
const markets = await getMarkets();
|
||||||
|
|
||||||
@ -37,101 +42,33 @@ export async function createMarket(cfg: {
|
|||||||
return markets;
|
return markets;
|
||||||
}
|
}
|
||||||
|
|
||||||
await setupEthereumAccount(
|
// To participate in governance (in this case proposing and voting in a market)
|
||||||
cfg.vegaPubKey,
|
// you need to have staked (associated) some Vega with a Vega public key
|
||||||
cfg.ethWalletMnemonic,
|
await stakeForVegaPublicKey(cfg.vegaPubKey);
|
||||||
cfg.ethereumProviderUrl
|
|
||||||
);
|
|
||||||
|
|
||||||
const result = await faucetAsset(cfg.faucetUrl, 'fUSDC', cfg.vegaPubKey);
|
// Send some of the asset for the market to be proposed to the test pubkey
|
||||||
|
const result = await faucetAsset(
|
||||||
|
cfg.faucetUrl,
|
||||||
|
ASSET_ID_FOR_MARKET,
|
||||||
|
cfg.vegaPubKey
|
||||||
|
);
|
||||||
if (!result.success) {
|
if (!result.success) {
|
||||||
throw new Error('faucet failed');
|
throw new Error('faucet failed');
|
||||||
}
|
}
|
||||||
|
|
||||||
// propose and vote on a market
|
// Propose a new market
|
||||||
const proposalTxResult = await proposeMarket(cfg.vegaPubKey, cfg.token);
|
const proposalTxResult = await proposeMarket(cfg.vegaPubKey);
|
||||||
const proposalId = determineId(proposalTxResult.transaction.signature.value);
|
const proposalId = determineId(proposalTxResult.transaction.signature.value);
|
||||||
log(`proposal created (id: ${proposalId})`);
|
log(`proposal created (id: ${proposalId})`);
|
||||||
const proposal = await waitForProposal(proposalId);
|
const proposal = await waitForProposal(proposalId);
|
||||||
await vote(
|
|
||||||
proposal.id,
|
// Vote on new market proposal
|
||||||
Schema.VoteValue.VALUE_YES,
|
await vote(proposal.id, Schema.VoteValue.VALUE_YES, cfg.vegaPubKey);
|
||||||
cfg.vegaPubKey,
|
|
||||||
cfg.token
|
// Wait for the market to be enacted and go into opening auction
|
||||||
);
|
|
||||||
await waitForEnactment();
|
await waitForEnactment();
|
||||||
|
|
||||||
// fetch and return created market
|
// Fetch the newly created market
|
||||||
const newMarkets = await getMarkets();
|
const newMarkets = await getMarkets();
|
||||||
return newMarkets;
|
return newMarkets;
|
||||||
}
|
}
|
||||||
|
|
||||||
async function getMarkets() {
|
|
||||||
const query = gql`
|
|
||||||
{
|
|
||||||
marketsConnection {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
id
|
|
||||||
decimalPlaces
|
|
||||||
positionDecimalPlaces
|
|
||||||
state
|
|
||||||
tradableInstrument {
|
|
||||||
instrument {
|
|
||||||
id
|
|
||||||
name
|
|
||||||
code
|
|
||||||
metadata {
|
|
||||||
tags
|
|
||||||
}
|
|
||||||
product {
|
|
||||||
... on Future {
|
|
||||||
settlementAsset {
|
|
||||||
id
|
|
||||||
symbol
|
|
||||||
decimals
|
|
||||||
}
|
|
||||||
quoteName
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const res = await requestGQL<{
|
|
||||||
marketsConnection: {
|
|
||||||
edges: Array<{
|
|
||||||
node: {
|
|
||||||
id: string;
|
|
||||||
decimalPlaces: number;
|
|
||||||
positionDecimalPlaces: number;
|
|
||||||
state: string;
|
|
||||||
tradableInstrument: {
|
|
||||||
instrument: {
|
|
||||||
id: string;
|
|
||||||
name: string;
|
|
||||||
code: string;
|
|
||||||
metadata: {
|
|
||||||
tags: string[];
|
|
||||||
};
|
|
||||||
product: {
|
|
||||||
settlementAssset: {
|
|
||||||
id: string;
|
|
||||||
symbol: string;
|
|
||||||
decimals: number;
|
|
||||||
};
|
|
||||||
quoteName: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}>;
|
|
||||||
};
|
|
||||||
}>(query);
|
|
||||||
|
|
||||||
return res.marketsConnection.edges.map((e) => e.node);
|
|
||||||
}
|
|
||||||
|
@ -1,28 +1,17 @@
|
|||||||
import { ethers, Wallet } from 'ethers';
|
|
||||||
import { StakingBridge, Token } from '@vegaprotocol/smart-contracts';
|
import { StakingBridge, Token } from '@vegaprotocol/smart-contracts';
|
||||||
import { gql } from 'graphql-request';
|
|
||||||
import { requestGQL } from './request';
|
|
||||||
import { createLog } from './logging';
|
import { createLog } from './logging';
|
||||||
|
import { promiseWithTimeout } from '../utils';
|
||||||
|
import { getVegaAsset } from './get-vega-asset';
|
||||||
|
import { getEthereumConfig } from './get-ethereum-config';
|
||||||
|
import { getPartyStake } from './get-party-stake';
|
||||||
|
import { wallet } from './ethereum-wallet';
|
||||||
|
|
||||||
const log = createLog('ethereum-setup');
|
const log = createLog('ethereum-setup');
|
||||||
|
|
||||||
export async function setupEthereumAccount(
|
export async function stakeForVegaPublicKey(vegaPublicKey: string) {
|
||||||
vegaPublicKey: string,
|
if (!wallet) {
|
||||||
ethWalletMnemonic: string,
|
throw new Error('ethereum wallet not initialized');
|
||||||
ethereumProviderUrl: string
|
}
|
||||||
) {
|
|
||||||
// create provider/wallet
|
|
||||||
const provider = new ethers.providers.JsonRpcProvider({
|
|
||||||
url: ethereumProviderUrl,
|
|
||||||
});
|
|
||||||
|
|
||||||
const privateKey = Wallet.fromMnemonic(
|
|
||||||
ethWalletMnemonic,
|
|
||||||
getAccount()
|
|
||||||
).privateKey;
|
|
||||||
|
|
||||||
// this wallet (ozone access etc) is already set up with 6 million vega (eth)
|
|
||||||
const wallet = new Wallet(privateKey, provider);
|
|
||||||
|
|
||||||
const vegaAsset = await getVegaAsset();
|
const vegaAsset = await getVegaAsset();
|
||||||
if (!vegaAsset) {
|
if (!vegaAsset) {
|
||||||
@ -43,13 +32,13 @@ export async function setupEthereumAccount(
|
|||||||
'100000' + '0'.repeat(18)
|
'100000' + '0'.repeat(18)
|
||||||
),
|
),
|
||||||
1000,
|
1000,
|
||||||
'tokenContract.approve'
|
'approve staking tx'
|
||||||
);
|
);
|
||||||
|
|
||||||
await promiseWithTimeout(
|
await promiseWithTimeout(
|
||||||
approveTx.wait(1),
|
approveTx.wait(1),
|
||||||
10 * 60 * 1000,
|
10 * 60 * 1000,
|
||||||
'approveTx.wait(1)'
|
'waiting for 1 stake approval confirmations'
|
||||||
);
|
);
|
||||||
log('sending approve tx: success');
|
log('sending approve tx: success');
|
||||||
|
|
||||||
@ -65,108 +54,27 @@ export async function setupEthereumAccount(
|
|||||||
14000,
|
14000,
|
||||||
'stakingContract.stake(amount, vegaPublicKey)'
|
'stakingContract.stake(amount, vegaPublicKey)'
|
||||||
);
|
);
|
||||||
await promiseWithTimeout(stakeTx.wait(3), 10 * 60 * 1000, 'stakeTx.wait(3)');
|
await promiseWithTimeout(
|
||||||
|
stakeTx.wait(3),
|
||||||
|
10 * 60 * 1000,
|
||||||
|
'waiting for 3 stake tx confirmations'
|
||||||
|
);
|
||||||
await waitForStake(vegaPublicKey);
|
await waitForStake(vegaPublicKey);
|
||||||
log(`sending stake tx: success`);
|
log(`sending stake tx: success`);
|
||||||
}
|
}
|
||||||
|
|
||||||
function timeout(time = 0, id: string) {
|
|
||||||
return new Promise((resolve, reject) => {
|
|
||||||
setTimeout(() => reject(new Error(`${id}: timeout triggered`)), time);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
async function promiseWithTimeout(
|
|
||||||
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
||||||
promise: Promise<any>,
|
|
||||||
time: number,
|
|
||||||
id: string
|
|
||||||
) {
|
|
||||||
return await Promise.race([promise, timeout(time, id)]);
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getVegaAsset() {
|
|
||||||
const query = gql`
|
|
||||||
{
|
|
||||||
assetsConnection {
|
|
||||||
edges {
|
|
||||||
node {
|
|
||||||
id
|
|
||||||
symbol
|
|
||||||
source {
|
|
||||||
... on ERC20 {
|
|
||||||
contractAddress
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const res = await requestGQL<{
|
|
||||||
assetsConnection: {
|
|
||||||
edges: Array<{
|
|
||||||
node: {
|
|
||||||
id: string;
|
|
||||||
symbol: string;
|
|
||||||
source: {
|
|
||||||
contractAddress: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}>;
|
|
||||||
};
|
|
||||||
}>(query);
|
|
||||||
return res.assetsConnection.edges
|
|
||||||
.map((e) => e.node)
|
|
||||||
.find((a) => a.symbol === 'VEGA');
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getEthereumConfig() {
|
|
||||||
const query = gql`
|
|
||||||
{
|
|
||||||
networkParameter(key: "blockchains.ethereumConfig") {
|
|
||||||
value
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
|
|
||||||
const res = await requestGQL<{
|
|
||||||
networkParameter: {
|
|
||||||
key: string;
|
|
||||||
value: string;
|
|
||||||
};
|
|
||||||
}>(query);
|
|
||||||
return JSON.parse(res.networkParameter.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
function waitForStake(vegaPublicKey: string) {
|
function waitForStake(vegaPublicKey: string) {
|
||||||
const query = gql`
|
|
||||||
{
|
|
||||||
party(id:"${vegaPublicKey}") {
|
|
||||||
stakingSummary {
|
|
||||||
currentStakeAvailable
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let tick = 1;
|
let tick = 1;
|
||||||
const interval = setInterval(async () => {
|
const interval = setInterval(async () => {
|
||||||
log(`confirming stake (attempt: ${tick})`);
|
log(`confirming stake (attempt: ${tick})`);
|
||||||
if (tick >= 10) {
|
if (tick >= 30) {
|
||||||
clearInterval(interval);
|
clearInterval(interval);
|
||||||
reject(new Error('stake link never seen'));
|
reject(new Error('stake link never seen'));
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await requestGQL<{
|
const res = await getPartyStake(vegaPublicKey);
|
||||||
party: {
|
|
||||||
stakingSummary: {
|
|
||||||
currentStakeAvailable: string;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
}>(query);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
res.party?.stakingSummary?.currentStakeAvailable !== null &&
|
res.party?.stakingSummary?.currentStakeAvailable !== null &&
|
||||||
@ -186,6 +94,3 @@ function waitForStake(vegaPublicKey: string) {
|
|||||||
}, 1000);
|
}, 1000);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
// derivation path
|
|
||||||
const getAccount = (number = 0) => `m/44'/60'/0'/0/${number}`;
|
|
||||||
|
24
libs/cypress/src/lib/capsule/ethereum-wallet.ts
Normal file
24
libs/cypress/src/lib/capsule/ethereum-wallet.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { ethers, Wallet } from 'ethers';
|
||||||
|
|
||||||
|
export let wallet: Wallet | undefined;
|
||||||
|
|
||||||
|
export function createEthereumWallet(
|
||||||
|
ethWalletMnemonic: string,
|
||||||
|
ethereumProviderUrl: string
|
||||||
|
) {
|
||||||
|
// create provider/wallet
|
||||||
|
const provider = new ethers.providers.JsonRpcProvider({
|
||||||
|
url: ethereumProviderUrl,
|
||||||
|
});
|
||||||
|
|
||||||
|
const privateKey = Wallet.fromMnemonic(
|
||||||
|
ethWalletMnemonic,
|
||||||
|
getAccount()
|
||||||
|
).privateKey;
|
||||||
|
|
||||||
|
// this wallet (ozone access etc) is already set up with 6 million vega (eth)
|
||||||
|
wallet = new Wallet(privateKey, provider);
|
||||||
|
}
|
||||||
|
|
||||||
|
// derivation path
|
||||||
|
const getAccount = (number = 0) => `m/44'/60'/0'/0/${number}`;
|
20
libs/cypress/src/lib/capsule/get-ethereum-config.ts
Normal file
20
libs/cypress/src/lib/capsule/get-ethereum-config.ts
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
import { gql } from 'graphql-request';
|
||||||
|
import { requestGQL } from './request';
|
||||||
|
|
||||||
|
export async function getEthereumConfig() {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
networkParameter(key: "blockchains.ethereumConfig") {
|
||||||
|
value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await requestGQL<{
|
||||||
|
networkParameter: {
|
||||||
|
key: string;
|
||||||
|
value: string;
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
return JSON.parse(res.networkParameter.value);
|
||||||
|
}
|
72
libs/cypress/src/lib/capsule/get-markets.ts
Normal file
72
libs/cypress/src/lib/capsule/get-markets.ts
Normal file
@ -0,0 +1,72 @@
|
|||||||
|
import { gql } from 'graphql-request';
|
||||||
|
import { requestGQL } from './request';
|
||||||
|
|
||||||
|
export async function getMarkets() {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
marketsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
decimalPlaces
|
||||||
|
positionDecimalPlaces
|
||||||
|
state
|
||||||
|
tradableInstrument {
|
||||||
|
instrument {
|
||||||
|
id
|
||||||
|
name
|
||||||
|
code
|
||||||
|
metadata {
|
||||||
|
tags
|
||||||
|
}
|
||||||
|
product {
|
||||||
|
... on Future {
|
||||||
|
settlementAsset {
|
||||||
|
id
|
||||||
|
symbol
|
||||||
|
decimals
|
||||||
|
}
|
||||||
|
quoteName
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await requestGQL<{
|
||||||
|
marketsConnection: {
|
||||||
|
edges: Array<{
|
||||||
|
node: {
|
||||||
|
id: string;
|
||||||
|
decimalPlaces: number;
|
||||||
|
positionDecimalPlaces: number;
|
||||||
|
state: string;
|
||||||
|
tradableInstrument: {
|
||||||
|
instrument: {
|
||||||
|
id: string;
|
||||||
|
name: string;
|
||||||
|
code: string;
|
||||||
|
metadata: {
|
||||||
|
tags: string[];
|
||||||
|
};
|
||||||
|
product: {
|
||||||
|
settlementAssset: {
|
||||||
|
id: string;
|
||||||
|
symbol: string;
|
||||||
|
decimals: number;
|
||||||
|
};
|
||||||
|
quoteName: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
|
||||||
|
return res.marketsConnection.edges.map((e) => e.node);
|
||||||
|
}
|
24
libs/cypress/src/lib/capsule/get-party-stake.ts
Normal file
24
libs/cypress/src/lib/capsule/get-party-stake.ts
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
import { gql } from 'graphql-request';
|
||||||
|
import { requestGQL } from './request';
|
||||||
|
|
||||||
|
export async function getPartyStake(partyId: string) {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
party(id:"${partyId}") {
|
||||||
|
stakingSummary {
|
||||||
|
currentStakeAvailable
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await requestGQL<{
|
||||||
|
party: {
|
||||||
|
stakingSummary: {
|
||||||
|
currentStakeAvailable: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
22
libs/cypress/src/lib/capsule/get-proposal.ts
Normal file
22
libs/cypress/src/lib/capsule/get-proposal.ts
Normal file
@ -0,0 +1,22 @@
|
|||||||
|
import { gql } from 'graphql-request';
|
||||||
|
import { requestGQL } from './request';
|
||||||
|
|
||||||
|
export async function getProposal(id: string) {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
proposal(id: "${id}") {
|
||||||
|
id
|
||||||
|
state
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await requestGQL<{
|
||||||
|
proposal: {
|
||||||
|
id: string;
|
||||||
|
state: string;
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
39
libs/cypress/src/lib/capsule/get-vega-asset.ts
Normal file
39
libs/cypress/src/lib/capsule/get-vega-asset.ts
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
import { gql } from 'graphql-request';
|
||||||
|
import { requestGQL } from './request';
|
||||||
|
|
||||||
|
export async function getVegaAsset() {
|
||||||
|
const query = gql`
|
||||||
|
{
|
||||||
|
assetsConnection {
|
||||||
|
edges {
|
||||||
|
node {
|
||||||
|
id
|
||||||
|
symbol
|
||||||
|
source {
|
||||||
|
... on ERC20 {
|
||||||
|
contractAddress
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
`;
|
||||||
|
|
||||||
|
const res = await requestGQL<{
|
||||||
|
assetsConnection: {
|
||||||
|
edges: Array<{
|
||||||
|
node: {
|
||||||
|
id: string;
|
||||||
|
symbol: string;
|
||||||
|
source: {
|
||||||
|
contractAddress: string;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
}>;
|
||||||
|
};
|
||||||
|
}>(query);
|
||||||
|
return res.assetsConnection.edges
|
||||||
|
.map((e) => e.node)
|
||||||
|
.find((a) => a.symbol === 'VEGA');
|
||||||
|
}
|
@ -1,24 +1,20 @@
|
|||||||
import * as Schema from '@vegaprotocol/types';
|
import * as Schema from '@vegaprotocol/types';
|
||||||
import { addSeconds, millisecondsToSeconds } from 'date-fns';
|
import { addSeconds, millisecondsToSeconds } from 'date-fns';
|
||||||
import { gql } from 'graphql-request';
|
|
||||||
import { request, requestGQL } from './request';
|
|
||||||
import { createLog } from './logging';
|
import { createLog } from './logging';
|
||||||
import type { ProposalSubmissionBody } from '@vegaprotocol/wallet';
|
import type { ProposalSubmissionBody } from '@vegaprotocol/wallet';
|
||||||
|
import { getProposal } from './get-proposal';
|
||||||
|
import { sendVegaTx } from './wallet-client';
|
||||||
|
import { ASSET_ID_FOR_MARKET } from './contants';
|
||||||
|
|
||||||
const log = createLog('propose-market');
|
const log = createLog('propose-market');
|
||||||
|
|
||||||
const MIN_CLOSE_SEC = 5;
|
const MIN_CLOSE_SEC = 5;
|
||||||
const MIN_ENACT_SEC = 3;
|
const MIN_ENACT_SEC = 3;
|
||||||
|
|
||||||
export async function proposeMarket(publicKey: string, token: string) {
|
export async function proposeMarket(publicKey: string) {
|
||||||
log('sending proposal tx');
|
log('sending proposal tx');
|
||||||
const proposalTx = createNewMarketProposal();
|
const proposalTx = createNewMarketProposal();
|
||||||
const result = await request('client.send_transaction', {
|
const result = await sendVegaTx(publicKey, proposalTx);
|
||||||
token,
|
|
||||||
publicKey,
|
|
||||||
sendingMode: 'TYPE_SYNC',
|
|
||||||
transaction: proposalTx,
|
|
||||||
});
|
|
||||||
|
|
||||||
return result.result;
|
return result.result;
|
||||||
}
|
}
|
||||||
@ -44,8 +40,8 @@ function createNewMarketProposal(): ProposalSubmissionBody {
|
|||||||
name: 'Test market 1',
|
name: 'Test market 1',
|
||||||
code: 'TEST.24h',
|
code: 'TEST.24h',
|
||||||
future: {
|
future: {
|
||||||
settlementAsset: 'fUSDC',
|
settlementAsset: ASSET_ID_FOR_MARKET,
|
||||||
quoteName: 'fUSDC',
|
quoteName: ASSET_ID_FOR_MARKET,
|
||||||
dataSourceSpecForSettlementData: {
|
dataSourceSpecForSettlementData: {
|
||||||
external: {
|
external: {
|
||||||
oracle: {
|
oracle: {
|
||||||
@ -144,14 +140,6 @@ function createNewMarketProposal(): ProposalSubmissionBody {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function waitForProposal(id: string): Promise<{ id: string }> {
|
export function waitForProposal(id: string): Promise<{ id: string }> {
|
||||||
const query = gql`
|
|
||||||
{
|
|
||||||
proposal(id: "${id}") {
|
|
||||||
id
|
|
||||||
state
|
|
||||||
}
|
|
||||||
}
|
|
||||||
`;
|
|
||||||
return new Promise((resolve, reject) => {
|
return new Promise((resolve, reject) => {
|
||||||
let tick = 0;
|
let tick = 0;
|
||||||
const interval = setInterval(async () => {
|
const interval = setInterval(async () => {
|
||||||
@ -161,13 +149,7 @@ export function waitForProposal(id: string): Promise<{ id: string }> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const res = await requestGQL<{
|
const res = await getProposal(id);
|
||||||
proposal: {
|
|
||||||
id: string;
|
|
||||||
state: string;
|
|
||||||
};
|
|
||||||
}>(query);
|
|
||||||
|
|
||||||
if (
|
if (
|
||||||
res.proposal !== null &&
|
res.proposal !== null &&
|
||||||
res.proposal.state === Schema.ProposalState.STATE_OPEN
|
res.proposal.state === Schema.ProposalState.STATE_OPEN
|
||||||
|
@ -1,39 +1,14 @@
|
|||||||
import { request as gqlRequest } from 'graphql-request';
|
import { request } from 'graphql-request';
|
||||||
|
|
||||||
let walletEndpoint = '';
|
|
||||||
let gqlEndpoint = '';
|
let gqlEndpoint = '';
|
||||||
|
|
||||||
export function setEndpoints(walletUrl: string, gqlUrl: string) {
|
export function setGraphQLEndpoint(gqlUrl: string) {
|
||||||
walletEndpoint = walletUrl + '/api/v2/requests';
|
|
||||||
gqlEndpoint = gqlUrl;
|
gqlEndpoint = gqlUrl;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function request(method: string, params: object) {
|
|
||||||
if (!walletEndpoint) {
|
|
||||||
throw new Error('gqlEndpoint not set');
|
|
||||||
}
|
|
||||||
const body = {
|
|
||||||
jsonrpc: '2.0',
|
|
||||||
method,
|
|
||||||
params,
|
|
||||||
id: Math.random().toString(),
|
|
||||||
};
|
|
||||||
return fetch(walletEndpoint, {
|
|
||||||
method: 'post',
|
|
||||||
body: JSON.stringify(body),
|
|
||||||
headers: {
|
|
||||||
'Content-Type': 'application/json',
|
|
||||||
Origin: 'market-setup',
|
|
||||||
Referer: 'market-setup',
|
|
||||||
},
|
|
||||||
}).then((res) => {
|
|
||||||
return res.json();
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
export function requestGQL<T>(query: string): Promise<T> {
|
export function requestGQL<T>(query: string): Promise<T> {
|
||||||
if (!gqlEndpoint) {
|
if (!gqlEndpoint) {
|
||||||
throw new Error('gqlEndpoint not set');
|
throw new Error('gqlEndpoint not set');
|
||||||
}
|
}
|
||||||
return gqlRequest(gqlEndpoint, query);
|
return request(gqlEndpoint, query);
|
||||||
}
|
}
|
||||||
|
@ -1,24 +1,18 @@
|
|||||||
import type * as Schema from '@vegaprotocol/types';
|
import type * as Schema from '@vegaprotocol/types';
|
||||||
import { request } from './request';
|
|
||||||
import { createLog } from './logging';
|
import { createLog } from './logging';
|
||||||
|
import { sendVegaTx } from './wallet-client';
|
||||||
|
|
||||||
const log = createLog('vote');
|
const log = createLog('vote');
|
||||||
|
|
||||||
export async function vote(
|
export async function vote(
|
||||||
proposalId: string,
|
proposalId: string,
|
||||||
voteValue: Schema.VoteValue,
|
voteValue: Schema.VoteValue,
|
||||||
publicKey: string,
|
publicKey: string
|
||||||
token: string
|
|
||||||
) {
|
) {
|
||||||
log(`voting ${voteValue} on ${proposalId}`);
|
log(`voting ${voteValue} on ${proposalId}`);
|
||||||
|
|
||||||
const voteTx = createVote(proposalId, voteValue);
|
const voteTx = createVote(proposalId, voteValue);
|
||||||
const voteResult = await request('client.send_transaction', {
|
const voteResult = await sendVegaTx(publicKey, voteTx);
|
||||||
token,
|
|
||||||
publicKey,
|
|
||||||
sendingMode: 'TYPE_SYNC',
|
|
||||||
transaction: voteTx,
|
|
||||||
});
|
|
||||||
|
|
||||||
return voteResult.result;
|
return voteResult.result;
|
||||||
}
|
}
|
||||||
|
56
libs/cypress/src/lib/capsule/wallet-client.ts
Normal file
56
libs/cypress/src/lib/capsule/wallet-client.ts
Normal file
@ -0,0 +1,56 @@
|
|||||||
|
import type { Transaction } from '@vegaprotocol/wallet';
|
||||||
|
|
||||||
|
let url = '';
|
||||||
|
let token = '';
|
||||||
|
let requestId = 1;
|
||||||
|
|
||||||
|
// Note: cant use @vegaprotocol/wallet-client due to webpack oddly not
|
||||||
|
// being able to handle class syntax. Instead heres a super basic 'client'
|
||||||
|
// which only sends transactions
|
||||||
|
export function createWalletClient(walletUrl: string, walletToken: string) {
|
||||||
|
url = walletUrl + '/api/v2/requests';
|
||||||
|
token = walletToken;
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function sendVegaTx(publicKey: string, transaction: Transaction) {
|
||||||
|
if (!url || !token) {
|
||||||
|
throw new Error('client not initialized');
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await request('client.send_transaction', {
|
||||||
|
publicKey,
|
||||||
|
transaction,
|
||||||
|
});
|
||||||
|
|
||||||
|
return res;
|
||||||
|
}
|
||||||
|
|
||||||
|
export function request(
|
||||||
|
method: string,
|
||||||
|
params: {
|
||||||
|
publicKey: string;
|
||||||
|
transaction: Transaction;
|
||||||
|
}
|
||||||
|
) {
|
||||||
|
const body = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method,
|
||||||
|
params: {
|
||||||
|
...params,
|
||||||
|
sendingMode: 'TYPE_SYNC',
|
||||||
|
token,
|
||||||
|
},
|
||||||
|
id: (requestId++).toString(),
|
||||||
|
};
|
||||||
|
return fetch(url, {
|
||||||
|
method: 'post',
|
||||||
|
body: JSON.stringify(body),
|
||||||
|
headers: {
|
||||||
|
'Content-Type': 'application/json',
|
||||||
|
Origin: 'market-setup',
|
||||||
|
Referer: 'market-setup',
|
||||||
|
},
|
||||||
|
}).then((res) => {
|
||||||
|
return res.json();
|
||||||
|
});
|
||||||
|
}
|
@ -10,19 +10,6 @@ declare global {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// suppress fetch and xhr logs
|
|
||||||
const originalLog = Cypress.log;
|
|
||||||
// @ts-ignore fuck with log to help with debug
|
|
||||||
Cypress.log = function (options, ...rest) {
|
|
||||||
// @ts-ignore fuck with log to help with debug
|
|
||||||
const isRequest = ['fetch', 'xhr'].includes(options.displayName);
|
|
||||||
if (isRequest) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
return originalLog(options, ...rest);
|
|
||||||
};
|
|
||||||
|
|
||||||
export const addCreateMarket = () => {
|
export const addCreateMarket = () => {
|
||||||
Cypress.Commands.add('createMarket', () => {
|
Cypress.Commands.add('createMarket', () => {
|
||||||
const config = {
|
const config = {
|
||||||
|
@ -18,3 +18,21 @@ export function removeDecimal(value: string, decimals: number): string {
|
|||||||
if (!decimals) return value;
|
if (!decimals) return value;
|
||||||
return new BigNumber(value || 0).times(Math.pow(10, decimals)).toFixed(0);
|
return new BigNumber(value || 0).times(Math.pow(10, decimals)).toFixed(0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function promiseWithTimeout(
|
||||||
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
|
promise: Promise<any>,
|
||||||
|
time: number,
|
||||||
|
name: string
|
||||||
|
) {
|
||||||
|
const rejectAfterTimeout = (time = 0) => {
|
||||||
|
return new Promise((resolve, reject) => {
|
||||||
|
setTimeout(
|
||||||
|
() => reject(new Error(`${name}: timed out after ${time}ms`)),
|
||||||
|
time
|
||||||
|
);
|
||||||
|
});
|
||||||
|
};
|
||||||
|
|
||||||
|
return await Promise.race([promise, rejectAfterTimeout(time)]);
|
||||||
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user