Skip to content

Commit d3c7bfb

Browse files
Merge pull request #589 from eoscommunity/main
EdenOS Release 0.2.22
2 parents 8325840 + 3630564 commit d3c7bfb

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

44 files changed

+1111
-379
lines changed

.github/workflows/build.yml

+4-2
Original file line numberDiff line numberDiff line change
@@ -250,7 +250,7 @@ jobs:
250250
- name: 🛠 Build and Start Box
251251
if: steps.filter.outputs.src == 'true'
252252
run: |
253-
export SUBCHAIN_DFUSE_PREVENT_CONNECT=1
253+
export DFUSE_PREVENT_CONNECT=1
254254
yarn
255255
yarn build --stream
256256
cd packages/box
@@ -376,7 +376,8 @@ jobs:
376376
- name: 🛠 Build and Start WebApp
377377
if: steps.filter.outputs.src == 'true'
378378
run: |
379-
export SUBCHAIN_DFUSE_PREVENT_CONNECT=1
379+
export DFUSE_PREVENT_CONNECT=1
380+
export NODE_ENV=test
380381
yarn
381382
yarn build --stream --ignore @edenos/example-history-app
382383
yarn start --stream --ignore @edenos/example-history-app &
@@ -463,3 +464,4 @@ jobs:
463464
file: docker/eden-webapp.Dockerfile
464465
tags: ${{ steps.prep.outputs.tags }}
465466
context: .
467+

contracts/eden/src/eden-micro-chain.cpp

+53-1
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,11 @@ constexpr eosio::name pool_account(eosio::name pool)
2626
constexpr eosio::name master_pool = pool_account("master"_n);
2727
eosio::name distribution_fund;
2828

29+
const eosio::name account_min = eosio::name{0};
30+
const eosio::name account_max = eosio::name{~uint64_t(0)};
31+
const eosio::block_timestamp block_timestamp_min = eosio::block_timestamp{0};
32+
const eosio::block_timestamp block_timestamp_max = eosio::block_timestamp{~uint32_t(0)};
33+
2934
// TODO: switch to uint64_t (js BigInt) after we upgrade to nodejs >= 15
3035
extern "C" void __wasm_call_ctors();
3136
[[clang::export_name("initialize")]] void initialize(uint32_t eden_account_low,
@@ -89,6 +94,7 @@ struct by_pk;
8994
struct by_invitee;
9095
struct by_group;
9196
struct by_round;
97+
struct by_createdAt;
9298

9399
template <typename T, typename... Indexes>
94100
using mic = boost::
@@ -119,6 +125,11 @@ using ordered_by_round = boost::multi_index::ordered_unique< //
119125
boost::multi_index::tag<by_round>,
120126
boost::multi_index::key<&T::by_round>>;
121127

128+
template <typename T>
129+
using ordered_by_createdAt = boost::multi_index::ordered_unique< //
130+
boost::multi_index::tag<by_createdAt>,
131+
boost::multi_index::key<&T::by_createdAt>>;
132+
122133
uint64_t available_pk(const auto& table, const auto& first)
123134
{
124135
auto& idx = table.template get<by_pk>();
@@ -294,6 +305,8 @@ using induction_index = mic<induction_object,
294305
ordered_by_pk<induction_object>,
295306
ordered_by_invitee<induction_object>>;
296307

308+
using MemberCreatedAtKey = std::pair<eosio::block_timestamp, eosio::name>;
309+
297310
struct member
298311
{
299312
eosio::name account;
@@ -302,6 +315,7 @@ struct member
302315
eden::new_member_profile profile;
303316
std::string inductionVideo;
304317
bool participating = false;
318+
eosio::block_timestamp createdAt;
305319
};
306320

307321
struct member_object : public chainbase::object<member_table, member_object>
@@ -312,8 +326,14 @@ struct member_object : public chainbase::object<member_table, member_object>
312326
member member;
313327

314328
eosio::name by_pk() const { return member.account; }
329+
MemberCreatedAtKey by_createdAt() const {
330+
return {member.createdAt, member.account};
331+
}
315332
};
316-
using member_index = mic<member_object, ordered_by_id<member_object>, ordered_by_pk<member_object>>;
333+
using member_index = mic<member_object,
334+
ordered_by_id<member_object>,
335+
ordered_by_pk<member_object>,
336+
ordered_by_createdAt<member_object>>;
317337

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

641662
MemberElectionConnection elections(std::optional<eosio::block_timestamp> gt,
642663
std::optional<eosio::block_timestamp> ge,
@@ -664,6 +685,7 @@ EOSIO_REFLECT2(
664685
profile,
665686
inductionVideo,
666687
participating,
688+
createdAt,
667689
method(elections, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
668690
method(distributionFunds, "gt", "ge", "lt", "le", "first", "last", "before", "after"))
669691

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

1799+
MemberConnection membersByCreatedAt(std::optional<eosio::block_timestamp> gt,
1800+
std::optional<eosio::block_timestamp> ge,
1801+
std::optional<eosio::block_timestamp> lt,
1802+
std::optional<eosio::block_timestamp> le,
1803+
std::optional<uint32_t> first,
1804+
std::optional<uint32_t> last,
1805+
std::optional<std::string> before,
1806+
std::optional<std::string> after) const
1807+
{
1808+
return clchain::make_connection<MemberConnection, MemberCreatedAtKey>(
1809+
gt ? std::optional{MemberCreatedAtKey{*gt, account_max}} //
1810+
: std::nullopt, //
1811+
ge ? std::optional{MemberCreatedAtKey{*ge, account_min}} //
1812+
: std::nullopt, //
1813+
lt ? std::optional{MemberCreatedAtKey{*lt, account_min}} //
1814+
: std::nullopt, //
1815+
le ? std::optional{MemberCreatedAtKey{*le, account_max}} //
1816+
: std::nullopt, //
1817+
first, last, before, after, //
1818+
db.members.get<by_createdAt>(), //
1819+
[](auto& obj) { return obj.by_createdAt(); }, //
1820+
[](auto& obj) {
1821+
return Member{obj.member.account, &obj.member};
1822+
},
1823+
[](auto& members, auto key) { return members.lower_bound(key); },
1824+
[](auto& members, auto key) { return members.upper_bound(key); });
1825+
}
1826+
17761827
ElectionConnection elections(std::optional<eosio::block_timestamp> gt,
17771828
std::optional<eosio::block_timestamp> ge,
17781829
std::optional<eosio::block_timestamp> lt,
@@ -1816,6 +1867,7 @@ EOSIO_REFLECT2(Query,
18161867
distributionFund,
18171868
method(balances, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
18181869
method(members, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
1870+
method(membersByCreatedAt, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
18191871
method(elections, "gt", "ge", "lt", "le", "first", "last", "before", "after"),
18201872
method(distributions, "gt", "ge", "lt", "le", "first", "last", "before", "after"))
18211873

packages/common/src/subchain/ReactSubchain.tsx

+23-5
Original file line numberDiff line numberDiff line change
@@ -45,22 +45,25 @@ export function useCreateEdenChain(
4545

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

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

55-
export function useQuery<T = any>(query: string): Query<T> {
55+
export function useQuery<T = any>(query: string): QueryResult<T> {
5656
const client = useContext(EdenChainContext);
5757
const [cachedQuery, setCachedQuery] = useState<string | null>();
5858
// non-signalling state
5959
const [state] = useState({
6060
mounted: true,
6161
cachedClient: null as SubchainClient | null,
6262
subscribed: null as SubchainClient | null,
63-
cachedQueryResult: { isLoading: false, isError: false } as Query<T>,
63+
cachedQueryResult: {
64+
isLoading: false,
65+
isError: false,
66+
} as QueryResult<T>,
6467
});
6568
useEffect(() => {
6669
return () => {
@@ -113,11 +116,26 @@ interface PageInfo {
113116
endCursor: string;
114117
}
115118

119+
export interface PagedQuery<T> {
120+
pageInfo: PageInfo;
121+
edges: T[];
122+
}
123+
124+
export interface PagedQueryResult<T> {
125+
result: QueryResult<T>;
126+
hasPreviousPage: boolean;
127+
hasNextPage: boolean;
128+
next(): void;
129+
previous(): void;
130+
first(): void;
131+
last(): void;
132+
}
133+
116134
export function usePagedQuery<T = any>(
117135
query: string,
118136
pageSize: number,
119-
getPageInfo: (result: Query<T>) => PageInfo | null | undefined
120-
) {
137+
getPageInfo: (result: QueryResult<T>) => PageInfo | null | undefined
138+
): PagedQueryResult<T> {
121139
const [args, setArgs] = useState(`first:${pageSize}`);
122140
const result = useQuery<T>(query.replace("@page@", args));
123141
const pageInfo = getPageInfo(result) || {

packages/webapp/.env

+32-20
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,54 @@
1+
# GENERAL APP
2+
NEXT_PUBLIC_APP_NAME = "Eden Community App"
3+
NEXT_PUBLIC_APP_SHORT_NAME = "eden-community-app"
14
NEXT_PUBLIC_BASE_URL = "http://localhost:3000"
5+
6+
# CHAIN/RPC
27
NEXT_PUBLIC_EOS_CHAIN_ID = "f16b1833c747c43682f4386fca9cbb327929334a762755ebec17f6f23c9b8a12"
38
NEXT_PUBLIC_EOS_RPC_PROTOCOL = "https"
4-
# NEXT_PUBLIC_EOS_RPC_HOST = "waxtestnet.greymass.com" # greymass wax is not 2.0 :(
59
NEXT_PUBLIC_EOS_RPC_HOST = "waxtest.eosn.io"
6-
# NEXT_PUBLIC_EOS_RPC_HOST = "jungle3.greymass.com"
710
NEXT_PUBLIC_EOS_RPC_PORT = "443"
811
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"
9-
NEXT_PUBLIC_BLOCKEXPLORER_ACCOUNT_BASE_URL = "https://wax-test.bloks.io/account"
12+
NEXT_PUBLIC_TABLE_ROWS_MAX_FETCH_PER_SEC = "10"
13+
14+
# CONTRACT
15+
NEXT_PUBLIC_EDEN_CONTRACT_ACCOUNT = "test.edev"
16+
NEXT_PUBLIC_AA_FETCH_AFTER="1633883520000"
17+
NEXT_PUBLIC_TOKEN_CONTRACT = "eosio.token"
18+
19+
# ATOMICHUB
1020
NEXT_PUBLIC_AA_BASE_URL = "https://test.wax.api.atomicassets.io/atomicassets/v1"
1121
NEXT_PUBLIC_AA_MARKET_URL = "https://test.wax.api.atomicassets.io/atomicmarket/v1"
1222
NEXT_PUBLIC_AA_HUB_URL = "https://wax-test.atomichub.io"
1323
NEXT_PUBLIC_AA_CONTRACT = "atomicassets"
1424
NEXT_PUBLIC_AA_MARKET_CONTRACT = "atomicmarket"
1525
NEXT_PUBLIC_AA_COLLECTION_NAME = "test.edev"
1626
NEXT_PUBLIC_AA_SCHEMA_NAME = "members"
17-
NEXT_PUBLIC_APP_SHORT_NAME = "eden-community-app"
18-
NEXT_PUBLIC_APP_NAME = "Eden Community App"
19-
NEXT_PUBLIC_EDEN_CONTRACT_ACCOUNT = "test.edev"
20-
NEXT_PUBLIC_AA_FETCH_AFTER="1631641671000"
21-
NEXT_PUBLIC_TOKEN_CONTRACT = "eosio.token"
22-
NEXT_PUBLIC_SUBCHAIN_WASM_URL = "http://localhost:3032/v1/subchain/eden-micro-chain.wasm"
23-
NEXT_PUBLIC_SUBCHAIN_STATE_URL = "http://localhost:3032/v1/subchain/state"
24-
NEXT_PUBLIC_SUBCHAIN_WS_URL = "ws://localhost:3032/v1/subchain/eden-microchain"
25-
NEXT_PUBLIC_SUBCHAIN_SLOW_MO = "false"
27+
28+
# OTHER
29+
NEXT_PUBLIC_BLOCKEXPLORER_ACCOUNT_BASE_URL = "https://wax-test.bloks.io/account"
2630
NEXT_PUBLIC_APP_MINIMUM_DONATION_AMOUNT = "10.00000000 WAX"
27-
# NEXT_PUBLIC_APP_MINIMUM_DONATION_AMOUNT = "10.0000 EOS"
2831
NEXT_PUBLIC_ENABLED_WALLETS = "ANCHOR,LEDGER,SOFTKEY"
29-
NEXT_PUBLIC_BOX_UPLOAD_IPFS = "true"
3032
NEXT_PUBLIC_IPFS_BASE_URL = "https://infura-ipfs.io/ipfs"
31-
NEXT_PUBLIC_BOX_ADDRESS = "https://box.dev.eoscommunity.org"
32-
NEXT_PUBLIC_ZOOM_CLIENT_ID = "8NOUvrD_RSqjrl96KU7h7Q"
33-
NEXT_PUBLIC_ELECTION_COMMUNITY_ROOM_URL = "[NOT SET]"
3433
NEXT_PUBLIC_DEV_USE_FIXTURE_DATA = "false"
35-
NEXT_PUBLIC_ELECTION_MEETING_DURATION_MS = "2400000"
34+
35+
# ELECTIONS
36+
NEXT_PUBLIC_ZOOM_CLIENT_ID = "8NOUvrD_RSqjrl96KU7h7Q"
3637
NEXT_PUBLIC_FREEFORM_MEETING_LINKS_ENABLED = "false"
37-
NEXT_PUBLIC_TABLE_ROWS_MAX_FETCH_PER_SEC = "10"
38+
NEXT_PUBLIC_ELECTION_MEETING_DURATION_MS = "2400000"
39+
NEXT_PUBLIC_ELECTION_COMMUNITY_ROOM_URL = "[NOT SET]"
40+
41+
# BOX: SUBCHAIN
42+
NEXT_PUBLIC_SUBCHAIN_WASM_URL = "http://localhost:3032/v1/subchain/eden-micro-chain.wasm"
43+
NEXT_PUBLIC_SUBCHAIN_STATE_URL = "http://localhost:3032/v1/subchain/state"
44+
NEXT_PUBLIC_SUBCHAIN_WS_URL = "ws://localhost:3032/v1/subchain/eden-microchain"
45+
NEXT_PUBLIC_SUBCHAIN_SLOW_MO = "false"
46+
47+
# BOX: IPFS
48+
NEXT_PUBLIC_BOX_ADDRESS = "http://localhost:3032"
49+
NEXT_PUBLIC_BOX_UPLOAD_IPFS = "true"
3850

39-
# Secrets Default
51+
# SECRETS DEFAULTS
4052
IPFS_PINATA_JWT = "<set-pinata-jwt-here>"
4153
IPFS_PINATA_API = "https://api.pinata.cloud/psa"
4254
JOBS_AUTH_GC = "<set-job-auth-gc>"

packages/webapp/.env.test

+17
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
# GENERAL APP
2+
NEXT_PUBLIC_BASE_URL = "https://cicd-box.dev.eoscommunity.org"
3+
4+
# CONTRACT
5+
NEXT_PUBLIC_EDEN_CONTRACT_ACCOUNT = "cicd.edev"
6+
NEXT_PUBLIC_AA_FETCH_AFTER="1634184000000"
7+
8+
# ATOMICHUB
9+
NEXT_PUBLIC_AA_COLLECTION_NAME = "cicd.edev"
10+
11+
# BOX: SUBCHAIN
12+
NEXT_PUBLIC_SUBCHAIN_WASM_URL = "https://cicd-box.dev.eoscommunity.org/v1/subchain/eden-micro-chain.wasm"
13+
NEXT_PUBLIC_SUBCHAIN_STATE_URL = "https://cicd-box.dev.eoscommunity.org/v1/subchain/state"
14+
NEXT_PUBLIC_SUBCHAIN_WS_URL = "wss://cicd-box.dev.eoscommunity.org/v1/subchain/eden-microchain"
15+
16+
# BOX: IPFS
17+
NEXT_PUBLIC_BOX_ADDRESS = "https://cicd-box.dev.eoscommunity.org"

packages/webapp/cypress/integration/community.spec.ts

+15-7
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,30 @@
11
describe("Community", () => {
22
beforeEach(() => {
3-
cy.visit(`/members`);
3+
cy.interceptSubchain();
44
cy.interceptEosApis();
5+
cy.viewport(1000, 1000);
6+
cy.visit(`/members`);
7+
cy.wait("@boxGetSubchain");
58
});
69

710
it("should display members", () => {
8-
const newMembersGrid = cy.get(`[data-testid="new-members-grid"]`);
9-
newMembersGrid.should("exist");
10-
const membersGrid = cy.get(`[data-testid="members-grid"]`);
11-
membersGrid.should("exist");
12-
membersGrid.find("div").should("have.length.greaterThan", 0);
11+
const membersList = cy.get(`[data-testid="members-list"]`);
12+
membersList.should("exist");
13+
membersList
14+
.children()
15+
.first()
16+
.children()
17+
.find("div")
18+
.should("have.length.greaterThan", 0);
1319
});
1420

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

1824
const firstMember = cy
19-
.get(`[data-testid="members-grid"]`)
25+
.get(`[data-testid="members-list"]`)
26+
.children()
27+
.first()
2028
.children()
2129
.first();
2230
firstMember.click();

packages/webapp/cypress/integration/inductions.spec.ts

+3-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,9 @@
11
describe("Inductions", () => {
22
beforeEach(() => {
3-
cy.visit(`/induction`);
3+
cy.interceptSubchain();
44
cy.interceptEosApis();
5+
cy.visit(`/induction`);
6+
cy.wait("@boxGetSubchain");
57
cy.wait("@eosGetTableRows");
68
});
79

packages/webapp/cypress/support/commands.ts

+9
Original file line numberDiff line numberDiff line change
@@ -29,13 +29,22 @@
2929
*/
3030
Cypress.Commands.add("login", (account) => {
3131
cy.get(`[data-testid="signin-nav-buttonsm"]`).first().click();
32+
cy.wait(500);
3233
cy.get("#ual-box div").contains("Password").click();
34+
cy.wait(500);
3335
cy.get('#ual-box input[type="text"]').type(account);
3436
cy.get("#ual-box div").contains("Continue").click();
3537
cy.get('input[type="password"]').type(Cypress.env("test_users_pk"));
3638
cy.get('button[type="submit"]').click();
3739
});
3840

41+
/**
42+
* Intercept Subchain Calls
43+
*/
44+
Cypress.Commands.add("interceptSubchain", () => {
45+
cy.intercept("**/v1/subchain/**").as("boxGetSubchain");
46+
});
47+
3948
/**
4049
* Intercept EOS RPC API Calls
4150
*/

packages/webapp/cypress/support/index.ts

+5
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,11 @@ declare namespace Cypress {
2424
*/
2525
login(account: string): Chainable;
2626

27+
/**
28+
* Intercepts and creates default aliases loading up Box Subchain
29+
*/
30+
interceptSubchain(): Chainable;
31+
2732
/**
2833
* Intercepts and creates default aliases for main EOS RPC Api Calls
2934
*/

0 commit comments

Comments
 (0)