Skip to content

Commit

Permalink
Merge pull request #589 from eoscommunity/main
Browse files Browse the repository at this point in the history
EdenOS Release 0.2.22
  • Loading branch information
brandonfancher authored Oct 26, 2021
2 parents 8325840 + 3630564 commit d3c7bfb
Show file tree
Hide file tree
Showing 44 changed files with 1,111 additions and 379 deletions.
6 changes: 4 additions & 2 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -250,7 +250,7 @@ jobs:
- name: 🛠 Build and Start Box
if: steps.filter.outputs.src == 'true'
run: |
export SUBCHAIN_DFUSE_PREVENT_CONNECT=1
export DFUSE_PREVENT_CONNECT=1
yarn
yarn build --stream
cd packages/box
Expand Down Expand Up @@ -376,7 +376,8 @@ jobs:
- name: 🛠 Build and Start WebApp
if: steps.filter.outputs.src == 'true'
run: |
export SUBCHAIN_DFUSE_PREVENT_CONNECT=1
export DFUSE_PREVENT_CONNECT=1
export NODE_ENV=test
yarn
yarn build --stream --ignore @edenos/example-history-app
yarn start --stream --ignore @edenos/example-history-app &
Expand Down Expand Up @@ -463,3 +464,4 @@ jobs:
file: docker/eden-webapp.Dockerfile
tags: ${{ steps.prep.outputs.tags }}
context: .

54 changes: 53 additions & 1 deletion contracts/eden/src/eden-micro-chain.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,11 @@ constexpr eosio::name pool_account(eosio::name pool)
constexpr eosio::name master_pool = pool_account("master"_n);
eosio::name distribution_fund;

const eosio::name account_min = eosio::name{0};
const eosio::name account_max = eosio::name{~uint64_t(0)};
const eosio::block_timestamp block_timestamp_min = eosio::block_timestamp{0};
const eosio::block_timestamp block_timestamp_max = eosio::block_timestamp{~uint32_t(0)};

// TODO: switch to uint64_t (js BigInt) after we upgrade to nodejs >= 15
extern "C" void __wasm_call_ctors();
[[clang::export_name("initialize")]] void initialize(uint32_t eden_account_low,
Expand Down Expand Up @@ -89,6 +94,7 @@ struct by_pk;
struct by_invitee;
struct by_group;
struct by_round;
struct by_createdAt;

template <typename T, typename... Indexes>
using mic = boost::
Expand Down Expand Up @@ -119,6 +125,11 @@ using ordered_by_round = boost::multi_index::ordered_unique< //
boost::multi_index::tag<by_round>,
boost::multi_index::key<&T::by_round>>;

template <typename T>
using ordered_by_createdAt = boost::multi_index::ordered_unique< //
boost::multi_index::tag<by_createdAt>,
boost::multi_index::key<&T::by_createdAt>>;

uint64_t available_pk(const auto& table, const auto& first)
{
auto& idx = table.template get<by_pk>();
Expand Down Expand Up @@ -294,6 +305,8 @@ using induction_index = mic<induction_object,
ordered_by_pk<induction_object>,
ordered_by_invitee<induction_object>>;

using MemberCreatedAtKey = std::pair<eosio::block_timestamp, eosio::name>;

struct member
{
eosio::name account;
Expand All @@ -302,6 +315,7 @@ struct member
eden::new_member_profile profile;
std::string inductionVideo;
bool participating = false;
eosio::block_timestamp createdAt;
};

struct member_object : public chainbase::object<member_table, member_object>
Expand All @@ -312,8 +326,14 @@ struct member_object : public chainbase::object<member_table, member_object>
member member;

eosio::name by_pk() const { return member.account; }
MemberCreatedAtKey by_createdAt() const {
return {member.createdAt, member.account};
}
};
using member_index = mic<member_object, ordered_by_id<member_object>, ordered_by_pk<member_object>>;
using member_index = mic<member_object,
ordered_by_id<member_object>,
ordered_by_pk<member_object>,
ordered_by_createdAt<member_object>>;

struct election_object : public chainbase::object<election_table, election_object>
{
Expand Down Expand Up @@ -637,6 +657,7 @@ struct Member
const eden::new_member_profile* profile() const { return member ? &member->profile : nullptr; }
const std::string* inductionVideo() const { return member ? &member->inductionVideo : nullptr; }
bool participating() const { return member && member->participating; }
eosio::block_timestamp createdAt() const { return member->createdAt; }

MemberElectionConnection elections(std::optional<eosio::block_timestamp> gt,
std::optional<eosio::block_timestamp> ge,
Expand Down Expand Up @@ -664,6 +685,7 @@ EOSIO_REFLECT2(
profile,
inductionVideo,
participating,
createdAt,
method(elections, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
method(distributionFunds, "gt", "ge", "lt", "le", "first", "last", "before", "after"))

Expand Down Expand Up @@ -1256,6 +1278,7 @@ void inductdonate(const action_context& context,
obj.member.inductionWitnesses = induction.induction.witnesses;
obj.member.profile = induction.induction.profile;
obj.member.inductionVideo = induction.induction.video;
obj.member.createdAt = eosio::block_timestamp(context.block.timestamp);
});
transfer_funds(context.block.timestamp, payer, master_pool, quantity,
history_desc::inductdonate);
Expand Down Expand Up @@ -1773,6 +1796,34 @@ struct Query
[](auto& members, auto key) { return members.upper_bound(key); });
}

MemberConnection membersByCreatedAt(std::optional<eosio::block_timestamp> gt,
std::optional<eosio::block_timestamp> ge,
std::optional<eosio::block_timestamp> lt,
std::optional<eosio::block_timestamp> le,
std::optional<uint32_t> first,
std::optional<uint32_t> last,
std::optional<std::string> before,
std::optional<std::string> after) const
{
return clchain::make_connection<MemberConnection, MemberCreatedAtKey>(
gt ? std::optional{MemberCreatedAtKey{*gt, account_max}} //
: std::nullopt, //
ge ? std::optional{MemberCreatedAtKey{*ge, account_min}} //
: std::nullopt, //
lt ? std::optional{MemberCreatedAtKey{*lt, account_min}} //
: std::nullopt, //
le ? std::optional{MemberCreatedAtKey{*le, account_max}} //
: std::nullopt, //
first, last, before, after, //
db.members.get<by_createdAt>(), //
[](auto& obj) { return obj.by_createdAt(); }, //
[](auto& obj) {
return Member{obj.member.account, &obj.member};
},
[](auto& members, auto key) { return members.lower_bound(key); },
[](auto& members, auto key) { return members.upper_bound(key); });
}

ElectionConnection elections(std::optional<eosio::block_timestamp> gt,
std::optional<eosio::block_timestamp> ge,
std::optional<eosio::block_timestamp> lt,
Expand Down Expand Up @@ -1816,6 +1867,7 @@ EOSIO_REFLECT2(Query,
distributionFund,
method(balances, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
method(members, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
method(membersByCreatedAt, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
method(elections, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
method(distributions, "gt", "ge", "lt", "le", "first", "last", "before", "after"))

Expand Down
28 changes: 23 additions & 5 deletions packages/common/src/subchain/ReactSubchain.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,22 +45,25 @@ export function useCreateEdenChain(

export const EdenChainContext = createContext<SubchainClient | null>(null);

export interface Query<T> {
export interface QueryResult<T> {
isLoading: boolean; // flags if the query is loading
data?: T; // has the query data when it's loaded or empty if not found
isError: boolean; // flags that an error happened
errors?: any; // contains the errors if there are any
}

export function useQuery<T = any>(query: string): Query<T> {
export function useQuery<T = any>(query: string): QueryResult<T> {
const client = useContext(EdenChainContext);
const [cachedQuery, setCachedQuery] = useState<string | null>();
// non-signalling state
const [state] = useState({
mounted: true,
cachedClient: null as SubchainClient | null,
subscribed: null as SubchainClient | null,
cachedQueryResult: { isLoading: false, isError: false } as Query<T>,
cachedQueryResult: {
isLoading: false,
isError: false,
} as QueryResult<T>,
});
useEffect(() => {
return () => {
Expand Down Expand Up @@ -113,11 +116,26 @@ interface PageInfo {
endCursor: string;
}

export interface PagedQuery<T> {
pageInfo: PageInfo;
edges: T[];
}

export interface PagedQueryResult<T> {
result: QueryResult<T>;
hasPreviousPage: boolean;
hasNextPage: boolean;
next(): void;
previous(): void;
first(): void;
last(): void;
}

export function usePagedQuery<T = any>(
query: string,
pageSize: number,
getPageInfo: (result: Query<T>) => PageInfo | null | undefined
) {
getPageInfo: (result: QueryResult<T>) => PageInfo | null | undefined
): PagedQueryResult<T> {
const [args, setArgs] = useState(`first:${pageSize}`);
const result = useQuery<T>(query.replace("@page@", args));
const pageInfo = getPageInfo(result) || {
Expand Down
52 changes: 32 additions & 20 deletions packages/webapp/.env
Original file line number Diff line number Diff line change
@@ -1,42 +1,54 @@
# GENERAL APP
NEXT_PUBLIC_APP_NAME = "Eden Community App"
NEXT_PUBLIC_APP_SHORT_NAME = "eden-community-app"
NEXT_PUBLIC_BASE_URL = "http://localhost:3000"

# CHAIN/RPC
NEXT_PUBLIC_EOS_CHAIN_ID = "f16b1833c747c43682f4386fca9cbb327929334a762755ebec17f6f23c9b8a12"
NEXT_PUBLIC_EOS_RPC_PROTOCOL = "https"
# NEXT_PUBLIC_EOS_RPC_HOST = "waxtestnet.greymass.com" # greymass wax is not 2.0 :(
NEXT_PUBLIC_EOS_RPC_HOST = "waxtest.eosn.io"
# NEXT_PUBLIC_EOS_RPC_HOST = "jungle3.greymass.com"
NEXT_PUBLIC_EOS_RPC_PORT = "443"
NEXT_PUBLIC_EOS_READ_RPC_URLS = "https://api.waxtest.alohaeos.com,https://wax-testnet.cryptolions.io,https://testnet.wax.pink.gg,https://testnet.waxsweden.org"
NEXT_PUBLIC_BLOCKEXPLORER_ACCOUNT_BASE_URL = "https://wax-test.bloks.io/account"
NEXT_PUBLIC_TABLE_ROWS_MAX_FETCH_PER_SEC = "10"

# CONTRACT
NEXT_PUBLIC_EDEN_CONTRACT_ACCOUNT = "test.edev"
NEXT_PUBLIC_AA_FETCH_AFTER="1633883520000"
NEXT_PUBLIC_TOKEN_CONTRACT = "eosio.token"

# ATOMICHUB
NEXT_PUBLIC_AA_BASE_URL = "https://test.wax.api.atomicassets.io/atomicassets/v1"
NEXT_PUBLIC_AA_MARKET_URL = "https://test.wax.api.atomicassets.io/atomicmarket/v1"
NEXT_PUBLIC_AA_HUB_URL = "https://wax-test.atomichub.io"
NEXT_PUBLIC_AA_CONTRACT = "atomicassets"
NEXT_PUBLIC_AA_MARKET_CONTRACT = "atomicmarket"
NEXT_PUBLIC_AA_COLLECTION_NAME = "test.edev"
NEXT_PUBLIC_AA_SCHEMA_NAME = "members"
NEXT_PUBLIC_APP_SHORT_NAME = "eden-community-app"
NEXT_PUBLIC_APP_NAME = "Eden Community App"
NEXT_PUBLIC_EDEN_CONTRACT_ACCOUNT = "test.edev"
NEXT_PUBLIC_AA_FETCH_AFTER="1631641671000"
NEXT_PUBLIC_TOKEN_CONTRACT = "eosio.token"
NEXT_PUBLIC_SUBCHAIN_WASM_URL = "http://localhost:3032/v1/subchain/eden-micro-chain.wasm"
NEXT_PUBLIC_SUBCHAIN_STATE_URL = "http://localhost:3032/v1/subchain/state"
NEXT_PUBLIC_SUBCHAIN_WS_URL = "ws://localhost:3032/v1/subchain/eden-microchain"
NEXT_PUBLIC_SUBCHAIN_SLOW_MO = "false"

# OTHER
NEXT_PUBLIC_BLOCKEXPLORER_ACCOUNT_BASE_URL = "https://wax-test.bloks.io/account"
NEXT_PUBLIC_APP_MINIMUM_DONATION_AMOUNT = "10.00000000 WAX"
# NEXT_PUBLIC_APP_MINIMUM_DONATION_AMOUNT = "10.0000 EOS"
NEXT_PUBLIC_ENABLED_WALLETS = "ANCHOR,LEDGER,SOFTKEY"
NEXT_PUBLIC_BOX_UPLOAD_IPFS = "true"
NEXT_PUBLIC_IPFS_BASE_URL = "https://infura-ipfs.io/ipfs"
NEXT_PUBLIC_BOX_ADDRESS = "https://box.dev.eoscommunity.org"
NEXT_PUBLIC_ZOOM_CLIENT_ID = "8NOUvrD_RSqjrl96KU7h7Q"
NEXT_PUBLIC_ELECTION_COMMUNITY_ROOM_URL = "[NOT SET]"
NEXT_PUBLIC_DEV_USE_FIXTURE_DATA = "false"
NEXT_PUBLIC_ELECTION_MEETING_DURATION_MS = "2400000"

# ELECTIONS
NEXT_PUBLIC_ZOOM_CLIENT_ID = "8NOUvrD_RSqjrl96KU7h7Q"
NEXT_PUBLIC_FREEFORM_MEETING_LINKS_ENABLED = "false"
NEXT_PUBLIC_TABLE_ROWS_MAX_FETCH_PER_SEC = "10"
NEXT_PUBLIC_ELECTION_MEETING_DURATION_MS = "2400000"
NEXT_PUBLIC_ELECTION_COMMUNITY_ROOM_URL = "[NOT SET]"

# BOX: SUBCHAIN
NEXT_PUBLIC_SUBCHAIN_WASM_URL = "http://localhost:3032/v1/subchain/eden-micro-chain.wasm"
NEXT_PUBLIC_SUBCHAIN_STATE_URL = "http://localhost:3032/v1/subchain/state"
NEXT_PUBLIC_SUBCHAIN_WS_URL = "ws://localhost:3032/v1/subchain/eden-microchain"
NEXT_PUBLIC_SUBCHAIN_SLOW_MO = "false"

# BOX: IPFS
NEXT_PUBLIC_BOX_ADDRESS = "http://localhost:3032"
NEXT_PUBLIC_BOX_UPLOAD_IPFS = "true"

# Secrets Default
# SECRETS DEFAULTS
IPFS_PINATA_JWT = "<set-pinata-jwt-here>"
IPFS_PINATA_API = "https://api.pinata.cloud/psa"
JOBS_AUTH_GC = "<set-job-auth-gc>"
Expand Down
17 changes: 17 additions & 0 deletions packages/webapp/.env.test
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
# GENERAL APP
NEXT_PUBLIC_BASE_URL = "https://cicd-box.dev.eoscommunity.org"

# CONTRACT
NEXT_PUBLIC_EDEN_CONTRACT_ACCOUNT = "cicd.edev"
NEXT_PUBLIC_AA_FETCH_AFTER="1634184000000"

# ATOMICHUB
NEXT_PUBLIC_AA_COLLECTION_NAME = "cicd.edev"

# BOX: SUBCHAIN
NEXT_PUBLIC_SUBCHAIN_WASM_URL = "https://cicd-box.dev.eoscommunity.org/v1/subchain/eden-micro-chain.wasm"
NEXT_PUBLIC_SUBCHAIN_STATE_URL = "https://cicd-box.dev.eoscommunity.org/v1/subchain/state"
NEXT_PUBLIC_SUBCHAIN_WS_URL = "wss://cicd-box.dev.eoscommunity.org/v1/subchain/eden-microchain"

# BOX: IPFS
NEXT_PUBLIC_BOX_ADDRESS = "https://cicd-box.dev.eoscommunity.org"
22 changes: 15 additions & 7 deletions packages/webapp/cypress/integration/community.spec.ts
Original file line number Diff line number Diff line change
@@ -1,22 +1,30 @@
describe("Community", () => {
beforeEach(() => {
cy.visit(`/members`);
cy.interceptSubchain();
cy.interceptEosApis();
cy.viewport(1000, 1000);
cy.visit(`/members`);
cy.wait("@boxGetSubchain");
});

it("should display members", () => {
const newMembersGrid = cy.get(`[data-testid="new-members-grid"]`);
newMembersGrid.should("exist");
const membersGrid = cy.get(`[data-testid="members-grid"]`);
membersGrid.should("exist");
membersGrid.find("div").should("have.length.greaterThan", 0);
const membersList = cy.get(`[data-testid="members-list"]`);
membersList.should("exist");
membersList
.children()
.first()
.children()
.find("div")
.should("have.length.greaterThan", 0);
});

it("should allow to view a member profile", () => {
cy.wait("@eosGetTableRows");

const firstMember = cy
.get(`[data-testid="members-grid"]`)
.get(`[data-testid="members-list"]`)
.children()
.first()
.children()
.first();
firstMember.click();
Expand Down
4 changes: 3 additions & 1 deletion packages/webapp/cypress/integration/inductions.spec.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
describe("Inductions", () => {
beforeEach(() => {
cy.visit(`/induction`);
cy.interceptSubchain();
cy.interceptEosApis();
cy.visit(`/induction`);
cy.wait("@boxGetSubchain");
cy.wait("@eosGetTableRows");
});

Expand Down
9 changes: 9 additions & 0 deletions packages/webapp/cypress/support/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,13 +29,22 @@
*/
Cypress.Commands.add("login", (account) => {
cy.get(`[data-testid="signin-nav-buttonsm"]`).first().click();
cy.wait(500);
cy.get("#ual-box div").contains("Password").click();
cy.wait(500);
cy.get('#ual-box input[type="text"]').type(account);
cy.get("#ual-box div").contains("Continue").click();
cy.get('input[type="password"]').type(Cypress.env("test_users_pk"));
cy.get('button[type="submit"]').click();
});

/**
* Intercept Subchain Calls
*/
Cypress.Commands.add("interceptSubchain", () => {
cy.intercept("**/v1/subchain/**").as("boxGetSubchain");
});

/**
* Intercept EOS RPC API Calls
*/
Expand Down
5 changes: 5 additions & 0 deletions packages/webapp/cypress/support/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@ declare namespace Cypress {
*/
login(account: string): Chainable;

/**
* Intercepts and creates default aliases loading up Box Subchain
*/
interceptSubchain(): Chainable;

/**
* Intercepts and creates default aliases for main EOS RPC Api Calls
*/
Expand Down
Loading

0 comments on commit d3c7bfb

Please sign in to comment.