-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
diff --git a/packages/o-editors/src/Pin/PinInput.svelte b/packages/o-editors/src/Pin/PinInput.svelte
new file mode 100644
index 000000000..fddf5e682
--- /dev/null
+++ b/packages/o-editors/src/Pin/PinInput.svelte
@@ -0,0 +1,140 @@
+
+
+
+ {#if inputs.length}
+ {#each inputs as item, i}
+ changeHandler(event, i)}"
+ placeholder="" />
+ {/each}
+ {/if}
+
+
+
diff --git a/packages/o-editors/src/Pin/PinInputEditor.svelte b/packages/o-editors/src/Pin/PinInputEditor.svelte
new file mode 100644
index 000000000..3a31c7750
--- /dev/null
+++ b/packages/o-editors/src/Pin/PinInputEditor.svelte
@@ -0,0 +1,134 @@
+
+
+
+
+
diff --git a/packages/o-editors/src/PostAddressEditor.svelte b/packages/o-editors/src/PostAddressEditor.svelte
new file mode 100644
index 000000000..9d320391c
--- /dev/null
+++ b/packages/o-editors/src/PostAddressEditor.svelte
@@ -0,0 +1,70 @@
+
+
+
diff --git a/packages/o-editors/src/ProcessNavigation.svelte b/packages/o-editors/src/ProcessNavigation.svelte
index 50f023b89..d006ef6b7 100644
--- a/packages/o-editors/src/ProcessNavigation.svelte
+++ b/packages/o-editors/src/ProcessNavigation.svelte
@@ -1,46 +1,54 @@
+ class="bottom-0 left-0 right-0 flex flex-col flex-grow w-full space-x-0 space-y-4 bg-white md:space-x-4 md:space-y-0 md:flex-row"
+ class:mt-6="{type != 'small'}"
+ class:sticky="{!noSticky}">
-
{
- dispatch("buttonClick");
- /* const answer = new Continue();
- answer.data = context.data;
- context.process.submit(answer);
- */
- }}
- class="btn btn-primary btn-block"
- >{context.params.submitButtonText
- ? context.params.submitButtonText
- : "Submit"}
-
-
-
-
+ {#if !context.params.hideNav}
+ {#if type == "large"}
+
{context.params.view && context.params.view.submitButtonText
+ ? context.params.view.submitButtonText
+ : "Submit"}
+
+
+
+
+ {:else if type == "small"}
+
+
+ {/if}
+ {/if}
diff --git a/packages/o-editors/src/QRCodeEditor.svelte b/packages/o-editors/src/QRCodeEditor.svelte
new file mode 100644
index 000000000..a28c22a0c
--- /dev/null
+++ b/packages/o-editors/src/QRCodeEditor.svelte
@@ -0,0 +1,133 @@
+
+
+
+
+
+
+
+
+ Camera: Environment Facing (default)
+ Camera: User Facing
+
+
+
+
+ Detected QR code:
+ None
+
+
+
diff --git a/packages/o-editors/src/QrCodeViewer.svelte b/packages/o-editors/src/QrCodeViewer.svelte
new file mode 100644
index 000000000..c88b7f33e
--- /dev/null
+++ b/packages/o-editors/src/QrCodeViewer.svelte
@@ -0,0 +1,94 @@
+
+
+
diff --git a/packages/o-editors/src/SimpleDropDownEditor.svelte b/packages/o-editors/src/SimpleDropDownEditor.svelte
new file mode 100644
index 000000000..c244233b7
--- /dev/null
+++ b/packages/o-editors/src/SimpleDropDownEditor.svelte
@@ -0,0 +1,201 @@
+
+
+{#if choices}
+
+{/if}
+
+
+
+
diff --git a/packages/o-editors/src/SingleButtonEditor.svelte b/packages/o-editors/src/SingleButtonEditor.svelte
new file mode 100644
index 000000000..8b29e4b86
--- /dev/null
+++ b/packages/o-editors/src/SingleButtonEditor.svelte
@@ -0,0 +1,50 @@
+
+
+
+ {#if context.messages[context.field]}
+
+
+
+
+
+
{context.messages[context.field]}
+
+
+ {/if}
+
+
+
diff --git a/packages/o-editors/src/TextEditor.svelte b/packages/o-editors/src/TextEditor.svelte
index 5466d4f17..9d320391c 100644
--- a/packages/o-editors/src/TextEditor.svelte
+++ b/packages/o-editors/src/TextEditor.svelte
@@ -1,74 +1,70 @@
diff --git a/packages/o-editors/src/TextViewer.svelte b/packages/o-editors/src/TextViewer.svelte
index ee1f3921b..f7dbb58d3 100644
--- a/packages/o-editors/src/TextViewer.svelte
+++ b/packages/o-editors/src/TextViewer.svelte
@@ -1,76 +1,49 @@
-
- {@html context.params.label}
+
+
+ {_context.data[context.field]}
+
+
{#if context.params.canCopy}
-
-
-
- Copy to Clipboard
-
-
-
+
+ {:else}
+
{/if}
-
-
-
- {_context.data[context.fieldName]}
-
-
diff --git a/packages/o-editors/src/TextareaEditor.svelte b/packages/o-editors/src/TextareaEditor.svelte
index eff222090..86fb71dbc 100644
--- a/packages/o-editors/src/TextareaEditor.svelte
+++ b/packages/o-editors/src/TextareaEditor.svelte
@@ -1,153 +1,129 @@
diff --git a/shell/src/dapps/o-banking/atoms/BankingDetailHeader.svelte b/shell/src/dapps/o-banking/atoms/BankingDetailHeader.svelte
deleted file mode 100644
index e9ef359bb..000000000
--- a/shell/src/dapps/o-banking/atoms/BankingDetailHeader.svelte
+++ /dev/null
@@ -1,56 +0,0 @@
-
-
-
-
-
-
- {#if classes == "transactionpositive"}
-
Received
- {:else if classes == "transactionnegative"}
-
Sent
- {:else}
-
Transfer
- {/if}
-
- {#if classes == "transactionpositive"}
- {Number.parseFloat(
- Web3.utils.fromWei(amount ? amount : "0", "ether")
- ).toFixed(2)}
- {:else if classes == "transactionnegative"}
- -{Number.parseFloat(
- Web3.utils.fromWei(amount ? amount : "0", "ether")
- ).toFixed(2)}
- {/if}
-
-
-
-
-
-
-
-
diff --git a/shell/src/dapps/o-banking/atoms/BankingHeader.svelte b/shell/src/dapps/o-banking/atoms/BankingHeader.svelte
index db239be4f..14901957f 100644
--- a/shell/src/dapps/o-banking/atoms/BankingHeader.svelte
+++ b/shell/src/dapps/o-banking/atoms/BankingHeader.svelte
@@ -1,56 +1,51 @@
-
+
-
-
-
Your Balance
-
{balance}
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+ {balanceTime}
+
+
+
+ BALANCE
+
+
+
+
-
- {#if !$mySafe.ui.loadingText || $mySafe.ui.loadingText === ""}
-
- {$mySafe.transfers && $mySafe.transfers.rows
- ? $mySafe.transfers.rows.length
- : ""} transactions
-
- {/if}
-
- {$mySafe.ui.loadingPercent ? $mySafe.ui.loadingText : ""}
-
-
-
-
+
diff --git a/shell/src/dapps/o-banking/atoms/TokenCard.svelte b/shell/src/dapps/o-banking/atoms/TokenCard.svelte
deleted file mode 100644
index a186a0ce5..000000000
--- a/shell/src/dapps/o-banking/atoms/TokenCard.svelte
+++ /dev/null
@@ -1,92 +0,0 @@
-
-
-
-
-
- {label ? label : ""}
-
-
-
-
-
-
-
-
-
-
-
-
- displayName == "You"
- ? false
- : loadDetailPage(token.tokenOwner)}
- >
-
- {displayName}
-
-
-
-
-
-
-
- {Number.parseFloat(
- Web3.utils.fromWei(token.balance ? token.balance : "0", "ether")
- ).toFixed(2)}
-
-
-
-
-
-
-
-
diff --git a/shell/src/dapps/o-banking/atoms/TransactionCard.svelte b/shell/src/dapps/o-banking/atoms/TransactionCard.svelte
index f98c80392..b9ee575bd 100644
--- a/shell/src/dapps/o-banking/atoms/TransactionCard.svelte
+++ b/shell/src/dapps/o-banking/atoms/TransactionCard.svelte
@@ -1,126 +1,197 @@
-
loadDetailPage(transfer._id)}
- class="flex items-center justify-center mb-2 text-circlesdarkblue"
->
-
-
-
-
-
+
+
+
+
+
+
+
+ {#if event.unread}
+ {targetProfile.displayName
+ ? targetProfile.displayName.length >= textCutoff
+ ? targetProfile.displayName.substr(0, textCutoff) + "..."
+ : targetProfile.displayName
+ : ""}
+ {:else}
+ {targetProfile.displayName
+ ? targetProfile.displayName.length >= textCutoff
+ ? targetProfile.displayName.substr(0, textCutoff) + "..."
+ : targetProfile.displayName
+ : ""}
+ {/if}
+
+
+
+ {amountTime}
+
+
+
+
+
+
+ {messageString
+ ? messageString.length >= textCutoff + 6
+ ? messageString.substr(0, textCutoff + 6) + "..."
+ : messageString
+ : ""}
+
+
-
-
-
-
- {displayName}
-
-
-
{message}
-
-
-
-
-
- {Number.parseFloat(
- Web3.utils.fromWei(transfer.amount, "ether")
- ).toFixed(2)}
-
-
-
- {#if transfer.time}
- {#if dateOlderThanSevenDays(transfer.time)}
-
- {:else}
-
- {/if}
- {/if}
-
-
-
-
+
+
diff --git a/shell/src/dapps/o-banking/atoms/TransferConfirmation.svelte b/shell/src/dapps/o-banking/atoms/TransferConfirmation.svelte
new file mode 100644
index 000000000..1a066bf66
--- /dev/null
+++ b/shell/src/dapps/o-banking/atoms/TransferConfirmation.svelte
@@ -0,0 +1,84 @@
+
+
+{#if _context.data && profile}
+
+
+
+ {_context.data.tokens.amount}
+
+
+
+
+
+
+
+
+
+ to {profile.displayName}
+
+
+
+ {_context.data.message ? _context.data.message : ""}
+
+
+
+
+
+
+
+
+
+
{profile.circlesAddress}
+
+
+
+
+{/if}
diff --git a/shell/src/dapps/o-banking/atoms/TransferSummary.svelte b/shell/src/dapps/o-banking/atoms/TransferSummary.svelte
new file mode 100644
index 000000000..476def405
--- /dev/null
+++ b/shell/src/dapps/o-banking/atoms/TransferSummary.svelte
@@ -0,0 +1,94 @@
+
+
+{#if _context.data && profile}
+
+
+
+ {_context.data.tokens.amount}
+
+
+
+
+
+
+
+
+
+ to {profile.displayName}
+
+
+
+ {_context.data.message ? _context.data.message : ""}
+
+
+
+
+
+
+
+
+
+
+
{profile.circlesAddress}
+
+
+
+
+
+
+
+
+
+
+ {_context.data.receipt ? _context.data.receipt.blockNumber : ""}
+
+
+
+
+
+
+
+
+
+
+
+ {_context.data.receipt ? _context.data.receipt.transactionHash : ""}
+
+
+
+
+{/if}
diff --git a/shell/src/dapps/o-banking/atoms/TrustCard.svelte b/shell/src/dapps/o-banking/atoms/TrustCard.svelte
deleted file mode 100644
index 85cb5dcf4..000000000
--- a/shell/src/dapps/o-banking/atoms/TrustCard.svelte
+++ /dev/null
@@ -1,217 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
loadDetailPage(safeAddress)}
- >
-
- {displayName}
-
-
-
- {#if untrusted}
-
- {/if}
- {#if trustedBy && trusting}
-
- {/if}
- {#if !(trustedBy && trusting) && trustedBy}
-
-
-
-
-
Is trusting you
-
- {/if}
- {#if !(trustedBy && trusting) && trusting}
-
- {/if}
-
-
-
-
-
execTransfer(safeAddress)}
- class="btn btn-square self-end btn-md btn-primary"
- >
-
-
-
-
-
-
-
-
-
diff --git a/shell/src/dapps/o-banking/atoms/TrustDetailHeader.svelte b/shell/src/dapps/o-banking/atoms/TrustDetailHeader.svelte
index 2414c1b32..1ff7637e1 100644
--- a/shell/src/dapps/o-banking/atoms/TrustDetailHeader.svelte
+++ b/shell/src/dapps/o-banking/atoms/TrustDetailHeader.svelte
@@ -1,15 +1,4 @@
-
-
-{#if isLoading}
-
-{:else}
-
-
-
+
+ {#if !isLoading}
+
+
+ class="rounded-full"
+ src="{profile && profile.avatarUrl ? profile.avatarUrl : ''}"
+ alt="Avatar of {profile.displayName}" />
-
+
- {profile ? profile.firstName : ""}
- {profile && profile.lastName ? profile.lastName : ""}
+ {profile ? profile.displayName : ''}
-
-{/if}
+ {/if}
+
diff --git a/shell/src/dapps/o-banking/atoms/XdaiAssetCard.svelte b/shell/src/dapps/o-banking/atoms/XdaiAssetCard.svelte
deleted file mode 100644
index 4776efc57..000000000
--- a/shell/src/dapps/o-banking/atoms/XdaiAssetCard.svelte
+++ /dev/null
@@ -1,43 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
- {title}
-
-
-
{address}
-
-
-
-
-
- {Number.parseFloat(balance).toFixed(2)}
-
-
-
-
-
-
diff --git a/shell/src/dapps/o-banking/data/api/codegen.yml b/shell/src/dapps/o-banking/data/api/codegen.yml
deleted file mode 100644
index cab54c7ea..000000000
--- a/shell/src/dapps/o-banking/data/api/codegen.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-schema: ./schema.graphql
-documents: './*.graphql'
-generates:
- ./types.ts:
- plugins:
- - typescript
- - typescript-operations
- - typescript-graphql-request
- config:
- useIndexSignature: true
diff --git a/shell/src/dapps/o-banking/data/api/queries.graphql b/shell/src/dapps/o-banking/data/api/queries.graphql
deleted file mode 100644
index 66224d15f..000000000
--- a/shell/src/dapps/o-banking/data/api/queries.graphql
+++ /dev/null
@@ -1,13 +0,0 @@
-query profilesByCirclesAddress($circlesAddresses:[String!]!) {
- profiles(query:{circlesAddress:$circlesAddresses}) {
- id
- circlesAddress
- firstName
- lastName
- dream
- country
- avatarUrl
- avatarCid
- avatarMimeType
- }
-}
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/api/schema.graphql b/shell/src/dapps/o-banking/data/api/schema.graphql
deleted file mode 100644
index 5d7c03f72..000000000
--- a/shell/src/dapps/o-banking/data/api/schema.graphql
+++ /dev/null
@@ -1,164 +0,0 @@
-# This file was generated based on ".graphqlconfig". Do not edit manually.
-
-schema {
- query: Query
- mutation: Mutation
-}
-
-type ConsumeDepositedChallengeResponse {
- challenge: String
- success: Boolean!
-}
-
-type DelegateAuthInit {
- appId: String!
- challengeType: String
- delegateAuthCode: String
- errorMessage: String
- success: Boolean!
- validTo: String
-}
-
-type DepositChallengeResponse {
- errorMessage: String
- success: Boolean!
-}
-
-type ExchangeTokenResponse {
- errorMessage: String
- success: Boolean!
-}
-
-type IndexTransferResponse {
- errorMessage: String
- success: Boolean!
-}
-
-type LogoutResponse {
- errorMessage: String
- success: Boolean!
-}
-
-type Mutation {
- authenticateAt(appId: String!): DelegateAuthInit!
- consumeDepositedChallenge(delegateAuthCode: String!): ConsumeDepositedChallengeResponse!
- depositChallenge(jwt: String!): DepositChallengeResponse!
- exchangeToken: ExchangeTokenResponse!
- indexTransfer(data: IndexTransferInput!): IndexTransferResponse!
- logout: LogoutResponse!
- requestUpdateSafe(data: RequestUpdateSafeInput!): RequestUpdateSafeResponse!
- updateSafe(data: UpdateSafeInput!): UpdateSafeResponse!
- upsertProfile(data: UpsertProfileInput!): Profile!
-}
-
-type Profile {
- avatarCid: String
- avatarMimeType: String
- avatarUrl: String
- circlesAddress: String
- circlesSafeOwner: String
- circlesTokenAddress: String
- country: String
- dream: String
- firstName: String!
- id: Int!
- lastName: String
- newsletter: Boolean
-}
-
-type Query {
- profiles(query: QueryProfileInput!): [Profile!]!
- search(query: SearchInput!): [Profile!]!
- sessionInfo: SessionInfo!
- version: Version!
- whoami: String
-}
-
-type RequestUpdateSafeResponse {
- challenge: String
- errorMessage: String
- success: Boolean!
-}
-
-type Server {
- version: String!
-}
-
-type SessionInfo {
- hasProfile: Boolean
- isLoggedOn: Boolean!
- profileId: Int
-}
-
-type UpdateSafeResponse {
- errorMessage: String
- newSafeAddress: String
- success: Boolean!
-}
-
-type Version {
- major: Int!
- minor: Int!
- revision: Int!
-}
-
-enum CacheControlScope {
- PRIVATE
- PUBLIC
-}
-
-input DepositChallenge {
- jwt: String!
-}
-
-input IndexTransferInput {
- amount: String!
- blockNo: Int!
- from: String!
- message: String!
- to: String!
-}
-
-input QueryProfileInput {
- circlesAddress: [String!]
- country: String
- firstName: String
- id: Int
- lastName: String
-}
-
-input QueryUniqueProfileInput {
- id: Int!
-}
-
-input RequestUpdateSafeInput {
- newSafeAddress: String!
-}
-
-input SearchInput {
- searchString: String!
-}
-
-input UpdateSafeInput {
- signature: String!
-}
-
-input UpsertProfileInput {
- avatarCid: String
- avatarMimeType: String
- avatarUrl: String
- circlesAddress: String
- circlesSafeOwner: String
- circlesTokenAddress: String
- country: String
- dream: String
- emailAddress: String
- firstName: String!
- id: Int
- lastName: String
- newsletter: Boolean
-}
-
-
-"The `Upload` scalar type represents a file upload."
-scalar Upload
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/api/types.ts b/shell/src/dapps/o-banking/data/api/types.ts
deleted file mode 100644
index 321bd774e..000000000
--- a/shell/src/dapps/o-banking/data/api/types.ts
+++ /dev/null
@@ -1,274 +0,0 @@
-import { GraphQLClient } from 'graphql-request';
-import { print } from 'graphql';
-import gql from 'graphql-tag';
-export type Maybe
= T | null;
-export type Exact = { [K in keyof T]: T[K] };
-export type MakeOptional = Omit & { [SubKey in K]?: Maybe };
-export type MakeMaybe = Omit & { [SubKey in K]: Maybe };
-/** All built-in and custom scalars, mapped to their actual values */
-export type Scalars = {
- ID: string;
- String: string;
- Boolean: boolean;
- Int: number;
- Float: number;
- /** The `Upload` scalar type represents a file upload. */
- Upload: any;
-};
-
-export enum CacheControlScope {
- Private = 'PRIVATE',
- Public = 'PUBLIC'
-}
-
-export type ConsumeDepositedChallengeResponse = {
- __typename?: 'ConsumeDepositedChallengeResponse';
- challenge?: Maybe;
- success: Scalars['Boolean'];
-};
-
-export type DelegateAuthInit = {
- __typename?: 'DelegateAuthInit';
- appId: Scalars['String'];
- challengeType?: Maybe;
- delegateAuthCode?: Maybe;
- errorMessage?: Maybe;
- success: Scalars['Boolean'];
- validTo?: Maybe;
-};
-
-export type DepositChallenge = {
- jwt: Scalars['String'];
-};
-
-export type DepositChallengeResponse = {
- __typename?: 'DepositChallengeResponse';
- errorMessage?: Maybe;
- success: Scalars['Boolean'];
-};
-
-export type ExchangeTokenResponse = {
- __typename?: 'ExchangeTokenResponse';
- errorMessage?: Maybe;
- success: Scalars['Boolean'];
-};
-
-export type IndexTransferInput = {
- amount: Scalars['String'];
- blockNo: Scalars['Int'];
- from: Scalars['String'];
- message: Scalars['String'];
- to: Scalars['String'];
-};
-
-export type IndexTransferResponse = {
- __typename?: 'IndexTransferResponse';
- errorMessage?: Maybe;
- success: Scalars['Boolean'];
-};
-
-export type LogoutResponse = {
- __typename?: 'LogoutResponse';
- errorMessage?: Maybe;
- success: Scalars['Boolean'];
-};
-
-export type Mutation = {
- __typename?: 'Mutation';
- authenticateAt: DelegateAuthInit;
- consumeDepositedChallenge: ConsumeDepositedChallengeResponse;
- depositChallenge: DepositChallengeResponse;
- exchangeToken: ExchangeTokenResponse;
- indexTransfer: IndexTransferResponse;
- logout: LogoutResponse;
- requestUpdateSafe: RequestUpdateSafeResponse;
- updateSafe: UpdateSafeResponse;
- upsertProfile: Profile;
-};
-
-
-export type MutationAuthenticateAtArgs = {
- appId: Scalars['String'];
-};
-
-
-export type MutationConsumeDepositedChallengeArgs = {
- delegateAuthCode: Scalars['String'];
-};
-
-
-export type MutationDepositChallengeArgs = {
- jwt: Scalars['String'];
-};
-
-
-export type MutationIndexTransferArgs = {
- data: IndexTransferInput;
-};
-
-
-export type MutationRequestUpdateSafeArgs = {
- data: RequestUpdateSafeInput;
-};
-
-
-export type MutationUpdateSafeArgs = {
- data: UpdateSafeInput;
-};
-
-
-export type MutationUpsertProfileArgs = {
- data: UpsertProfileInput;
-};
-
-export type Profile = {
- __typename?: 'Profile';
- avatarCid?: Maybe;
- avatarMimeType?: Maybe;
- avatarUrl?: Maybe;
- circlesAddress?: Maybe;
- circlesSafeOwner?: Maybe;
- circlesTokenAddress?: Maybe;
- country?: Maybe;
- dream?: Maybe;
- firstName: Scalars['String'];
- id: Scalars['Int'];
- lastName?: Maybe;
- newsletter?: Maybe;
-};
-
-export type Query = {
- __typename?: 'Query';
- profiles: Array;
- search: Array;
- sessionInfo: SessionInfo;
- version: Version;
- whoami?: Maybe;
-};
-
-
-export type QueryProfilesArgs = {
- query: QueryProfileInput;
-};
-
-
-export type QuerySearchArgs = {
- query: SearchInput;
-};
-
-export type QueryProfileInput = {
- circlesAddress?: Maybe>;
- country?: Maybe;
- firstName?: Maybe;
- id?: Maybe;
- lastName?: Maybe;
-};
-
-export type QueryUniqueProfileInput = {
- id: Scalars['Int'];
-};
-
-export type RequestUpdateSafeInput = {
- newSafeAddress: Scalars['String'];
-};
-
-export type RequestUpdateSafeResponse = {
- __typename?: 'RequestUpdateSafeResponse';
- challenge?: Maybe;
- errorMessage?: Maybe;
- success: Scalars['Boolean'];
-};
-
-export type SearchInput = {
- searchString: Scalars['String'];
-};
-
-export type Server = {
- __typename?: 'Server';
- version: Scalars['String'];
-};
-
-export type SessionInfo = {
- __typename?: 'SessionInfo';
- hasProfile?: Maybe;
- isLoggedOn: Scalars['Boolean'];
- profileId?: Maybe;
-};
-
-export type UpdateSafeInput = {
- signature: Scalars['String'];
-};
-
-export type UpdateSafeResponse = {
- __typename?: 'UpdateSafeResponse';
- errorMessage?: Maybe;
- newSafeAddress?: Maybe;
- success: Scalars['Boolean'];
-};
-
-
-export type UpsertProfileInput = {
- avatarCid?: Maybe;
- avatarMimeType?: Maybe;
- avatarUrl?: Maybe;
- circlesAddress?: Maybe;
- circlesSafeOwner?: Maybe;
- circlesTokenAddress?: Maybe;
- country?: Maybe;
- dream?: Maybe;
- emailAddress?: Maybe;
- firstName: Scalars['String'];
- id?: Maybe;
- lastName?: Maybe;
- newsletter?: Maybe;
-};
-
-export type Version = {
- __typename?: 'Version';
- major: Scalars['Int'];
- minor: Scalars['Int'];
- revision: Scalars['Int'];
-};
-
-export type ProfilesByCirclesAddressQueryVariables = Exact<{
- circlesAddresses: Array | Scalars['String'];
-}>;
-
-
-export type ProfilesByCirclesAddressQuery = (
- { __typename?: 'Query' }
- & { profiles: Array<(
- { __typename?: 'Profile' }
- & Pick
- )> }
-);
-
-
-export const ProfilesByCirclesAddressDocument = gql`
- query profilesByCirclesAddress($circlesAddresses: [String!]!) {
- profiles(query: {circlesAddress: $circlesAddresses}) {
- id
- circlesAddress
- firstName
- lastName
- dream
- country
- avatarUrl
- avatarCid
- avatarMimeType
- }
-}
- `;
-
-export type SdkFunctionWrapper = (action: () => Promise) => Promise;
-
-
-const defaultWrapper: SdkFunctionWrapper = sdkFunction => sdkFunction();
-export function getSdk(client: GraphQLClient, withWrapper: SdkFunctionWrapper = defaultWrapper) {
- return {
- profilesByCirclesAddress(variables: ProfilesByCirclesAddressQueryVariables): Promise {
- return withWrapper(() => client.request(print(ProfilesByCirclesAddressDocument), variables));
- }
- };
-}
-export type Sdk = ReturnType;
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/apiProfile.ts b/shell/src/dapps/o-banking/data/apiProfile.ts
deleted file mode 100644
index 3cff6074b..000000000
--- a/shell/src/dapps/o-banking/data/apiProfile.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export type ApiProfile = {
- id?: number;
- avatarUrl?: string;
- dream?: string;
- country?: string;
- circlesAddress?: string;
- circlesSafeOwner?: string;
- firstName: string;
- lastName?: string;
-};
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/augmentSafeWithProfiles.ts b/shell/src/dapps/o-banking/data/augmentSafeWithProfiles.ts
deleted file mode 100644
index 14a6926a8..000000000
--- a/shell/src/dapps/o-banking/data/augmentSafeWithProfiles.ts
+++ /dev/null
@@ -1,133 +0,0 @@
-import {ProfilesByCirclesAddressDocument} from "./api/types";
-import {RpcGateway} from "@o-platform/o-circles/dist/rpcGateway";
-import {Safe} from "./circles/types";
-
-async function loadProfilesBySafeAddress(circlesAddresses: string[]) {
- const apiClient = await window.o.apiClient.client.subscribeToResult();
- const result = await apiClient.query({
- query: ProfilesByCirclesAddressDocument,
- variables: {
- circlesAddresses: circlesAddresses
- }
- });
-
- console.log("All profiles in transactions list:", result.data.profiles)
- return result.data.profiles.map(p => {
- return {
- ...p,
- circlesAddress : RpcGateway.get().utils.toChecksumAddress(p.circlesAddress)
- }
- });
-}
-
-async function loadCirclesGardenProfilesBySafeAddress(circlesAddresses: string[]) {
- const baseUrl = `https://api.circles.garden/api/users/`;
- if (circlesAddresses.length == 0) {
- return [];
- }
- let query = circlesAddresses.reduce((p, c) => p + `address[]=${RpcGateway.get().utils.toChecksumAddress(c)}&`, "");
- query = query.substr(0, query.length - 1);
- console.log("Querying the following profiles from the circles garden api:", query);
-
- const result = await fetch(`${baseUrl}?${query}`);
- const resultJson = await result.json();
- console.log(resultJson);
-
- return resultJson.data;
-}
-
-async function createProfileMap(safeAddresses:string[]) {
- const profiles = await Promise.all([
- loadProfilesBySafeAddress(safeAddresses),
- loadCirclesGardenProfilesBySafeAddress(safeAddresses)
- ]);
- const map:{
- [safeAddress:string]:{
- safeAddress: string
- displayName: string
- avatarUrl: string
- }
- } = {};
- const garden = profiles[1];
- garden.forEach(profile => {
- map[profile.safeAddress] = {
- safeAddress: profile.safeAddress,
- displayName: `${profile.username}`,
- avatarUrl: profile.avatarUrl
- };
- });
- const land = profiles[0];
- land.forEach(profile => {
- map[profile.circlesAddress] = {
- safeAddress: profile.circlesAddress,
- displayName: `${profile.firstName} ${profile.lastName ?? ""}`,
- avatarUrl: profile.avatarUrl
- };
- });
- return map;
-}
-
-function findAllSafeAddresses(safe:Safe) {
- const addresses: {[safeAddress:string]: null} = {};
-
- addresses[safe.safeAddress.toLowerCase()] = null;
-
- // First: Add the own address
- if (safe.safeAddress) {
- addresses[safe.safeAddress] = null;
- }
-
- // Then add all transfer participants
- if (safe.transfers?.rows) {
- safe.transfers.rows.forEach(transfer => {
- addresses[transfer.from] = null;
- addresses[transfer.to] = null;
- });
- }
-
- const trusts = Object.values(safe.trustRelations?.trusting ?? {}).concat(Object.values(safe.trustRelations?.trustedBy ?? {}));
- trusts.forEach(trust => {
- addresses[trust.safeAddress] = null;
- });
-
- return Object.keys(addresses);
-}
-
-function tryGetSimplifiedProfile(profileMap:{[safeAddress:string]:any}, safeAddress:string) : {
- safeAddress: string
- displayName: string
- avatarUrl: string
-} {
- return profileMap[safeAddress];
-}
-
-export async function augmentSafeWithProfiles(safe:Safe) {
- const allAddresses = findAllSafeAddresses(safe);
- const profiles = await createProfileMap(allAddresses);
-
- // First: Add the own address
- if (safe.safeAddress && safe.token) {
- safe.token.ownerProfile = tryGetSimplifiedProfile(profiles, RpcGateway.get().utils.toChecksumAddress(safe.safeAddress))
- }
-
- // Then add all transfer participants
- if (safe.transfers?.rows) {
- safe.transfers.rows.forEach(transfer => {
- transfer.fromProfile = tryGetSimplifiedProfile(profiles, transfer.from);
- transfer.toProfile = tryGetSimplifiedProfile(profiles, transfer.to);
- });
- }
-
- const trusts = Object.values(safe.trustRelations?.trusting ?? {})
- .concat(Object.values(safe.trustRelations?.trustedBy ?? {}))
- .concat(Object.values(safe.trustRelations?.untrusted ?? {}));
- trusts.forEach(trust => {
- trust.profile = tryGetSimplifiedProfile(profiles, trust.safeAddress);
- });
-
- if (safe.acceptedTokens && safe.acceptedTokens.tokens) {
- for (let tokensKey in safe.acceptedTokens.tokens) {
- safe.acceptedTokens.tokens[tokensKey].ownerProfile = tryGetSimplifiedProfile(profiles, safe.acceptedTokens.tokens[tokensKey].tokenOwner);
- }
- }
-}
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/augmentSafeWithTime.ts b/shell/src/dapps/o-banking/data/augmentSafeWithTime.ts
deleted file mode 100644
index d7185bbb1..000000000
--- a/shell/src/dapps/o-banking/data/augmentSafeWithTime.ts
+++ /dev/null
@@ -1,42 +0,0 @@
-import {RpcGateway} from "@o-platform/o-circles/dist/rpcGateway";
-import {Safe} from "./circles/types";
-
-export async function augmentSafeWithTime(safe: Safe) {
- let avgBlockTime: number = 5.2;
- let sampleRate: number = 20;
- let lastTimestamp: number = null;
- let lastTimestampBlockNo: number = null;
-
- let allTransactions = Object.values(safe.transfers.rows);
-
- for (let transactionIndex = 0; transactionIndex < allTransactions.length; transactionIndex++) {
- const transaction = allTransactions[transactionIndex];
-
- try {
- if (!lastTimestamp || transactionIndex % sampleRate == 0) {
- if (transaction.time) {
- lastTimestamp = transaction.time;
- lastTimestampBlockNo = transaction.firstBlock;
- } else {
- const block = await RpcGateway.get().eth.getBlock(transaction.firstBlock);
- if (typeof block.timestamp === "string") {
- lastTimestamp = parseInt(block.timestamp);
- } else {
- lastTimestamp = block.timestamp;
- }
- lastTimestampBlockNo = transaction.firstBlock;
- }
- }
-
- const passedBlocksSinceLastTimestampBlockNo = lastTimestampBlockNo - transaction.firstBlock;
- const passedSecondsSinceLastTimestamp = passedBlocksSinceLastTimestampBlockNo * avgBlockTime;
- const currentBlockTimestamp = lastTimestamp - passedSecondsSinceLastTimestamp;
-
- if (!transaction.time) {
- transaction.time = parseInt(currentBlockTimestamp.toFixed());
- }
- } catch (e) {
- console.warn("Couldn't determine the time of block " + transaction.firstBlock + ": " + e.toString());
- }
- }
-}
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/augmentTransactionsWithMessages.ts b/shell/src/dapps/o-banking/data/augmentTransactionsWithMessages.ts
deleted file mode 100644
index 307661d53..000000000
--- a/shell/src/dapps/o-banking/data/augmentTransactionsWithMessages.ts
+++ /dev/null
@@ -1,47 +0,0 @@
-import {Safe} from "./circles/types";
-import {RpcGateway} from "@o-platform/o-circles/dist/rpcGateway";
-
-export async function augmentSafeWithProfiles(safe:Safe) {
-/*
- fetch("https://api.circles.garden/api/transfers/0xa9ae71e783b858105fab3fcd61e4f624df19218b68a271c8743685db5c326ffc/", {
- "body": "{\"address\":\"0x9B74661e83F6696AdF872576f886Dc5Eb569B0bD\",\"signature\":\"0x05236302793a245794c1d6f2a3af3f510ee07aeb3ef0369d93e85d7d9613994c1d03aacaf63bbf4618334d80d50808186a02ad7ab82d070f40c009f011ca21ba1b\"}",
- "method": "POST",
- "mode": "cors",
- "credentials": "omit"
- });
-
- let allTransactions = Object.values(safe.transfers.rows);
-
- for (let transactionIndex = 0; transactionIndex < allTransactions.length; transactionIndex++) {
- const transaction = allTransactions[transactionIndex];
-
- try {
- if (!lastTimestamp || transactionIndex % sampleRate == 0) {
- if (transaction.time) {
- lastTimestamp = transaction.time;
- lastTimestampBlockNo = transaction.firstBlock;
- } else {
- const block = await RpcGateway.get().eth.getBlock(transaction.firstBlock);
- if (typeof block.timestamp === "string") {
- lastTimestamp = parseInt(block.timestamp);
- } else {
- lastTimestamp = block.timestamp;
- }
- lastTimestampBlockNo = transaction.firstBlock;
- }
- }
-
- const passedBlocksSinceLastTimestampBlockNo = lastTimestampBlockNo - transaction.firstBlock;
- const passedSecondsSinceLastTimestamp = passedBlocksSinceLastTimestampBlockNo * avgBlockTime;
- const currentBlockTimestamp = lastTimestamp - passedSecondsSinceLastTimestamp;
-
- if (!transaction.time) {
- transaction.time = parseInt(currentBlockTimestamp.toFixed());
- }
- } catch (e) {
- console.warn("Couldn't determine the time of block " + transaction.firstBlock + ": " + e.toString());
- }
- }
- */
- return safe;
-}
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/circles/queries.ts b/shell/src/dapps/o-banking/data/circles/queries.ts
deleted file mode 100644
index 3d3c30782..000000000
--- a/shell/src/dapps/o-banking/data/circles/queries.ts
+++ /dev/null
@@ -1,380 +0,0 @@
-import {CirclesAccount} from "@o-platform/o-circles/dist/model/circlesAccount";
-import {BlockchainEvent} from "@o-platform/o-events/dist/blockchainEvent";
-import {RpcGateway} from "@o-platform/o-circles/dist/rpcGateway";
-import {Erc20Token} from "@o-platform/o-circles/dist/token/erc20Token";
-import {Observable, Subject} from "rxjs";
-import {CirclesToken} from "@o-platform/o-circles/dist/model/circlesToken";
-import {PlatformEvent} from "@o-platform/o-events/dist/platformEvent";
-import {Safe, Token, Transfer, TrustObject} from "./types";
-
-export class Queries {
- static async addOwnToken(safe: Safe): Promise {
- if (RpcGateway.get().utils.isAddress(safe.token?.tokenAddress ?? "")) {
- console.log("skipping addOwnToken()")
- return safe;
- }
- const checksumSafeAddress = RpcGateway.get().utils.toChecksumAddress(safe.safeAddress);
- const foundTokenOrNull = await new CirclesAccount(checksumSafeAddress).tryGetMyToken(!!safe.firstBlock ? safe.firstBlock : undefined);
- if (!foundTokenOrNull) {
- console.log("The safe isn't yet signed-up at the circles hub")
- } else {
- (foundTokenOrNull).limit = 100;
- }
-
- return {
- ...safe,
- token: foundTokenOrNull
- }
- }
-
- static async addxDaiBalances(safe: Safe) : Promise {
- return {
- ...safe,
- xDaiBalance: await RpcGateway.get().eth.getBalance(safe.safeAddress),
- accountxDai: localStorage.getItem("circlesAccount") ? await RpcGateway.get().eth.getBalance(localStorage.getItem("circlesAccount")) : "0",
- }
- }
-
- static async addTokenBalances(safe: Safe) : Promise {
- const tokens = safe.acceptedTokens.tokens;
- const promises = Object.keys(tokens).map(address => tokens[address])
- .map(async token => {
- token.balance = (await new Erc20Token(RpcGateway.get(), token.tokenAddress).getBalanceOf(safe.safeAddress)).toString();
- });
-
- await Promise.all(promises);
-
- return {
- ...safe,
- acceptedTokens: {
- ...safe.acceptedTokens,
- tokens
- }
- }
- }
-
- static async addAcceptedTokens(safe: Safe): Promise {
- if (!safe.trustRelations?.trusting) {
- throw new Error(`The 'trusting' property of safe ${safe.safeAddress} must be populated in order to call 'addAcceptedTokens()'`);
- }
-
- const acceptedTokens = safe.acceptedTokens ?? {
- firstBlock: 0,
- lastBlock: 0,
- tokens: {}
- };
-
- const trustedBy = Object.keys(safe.trustRelations.trusting).map(address => safe.trustRelations.trusting[address]);
- const requests = trustedBy.map(async trust => {
- const checksumSafeAddress = RpcGateway.get().utils.toChecksumAddress(trust.safeAddress);
- return {
- token: (await this.addOwnToken({safeAddress: checksumSafeAddress})).token,
- limit: trust.limit,
- lastTrustBlock: trust.lastBlock
- };
- });
- const trustedByTokens = await Promise.all(requests);
- trustedByTokens.filter(o => o.token)
- .forEach(acceptedToken => {
- let firstBlock:number = undefined;
- let lastBlock:number = undefined;
- let limit = undefined;
- if (acceptedTokens.tokens[acceptedToken.token.tokenAddress]) {
- firstBlock = acceptedTokens.tokens[acceptedToken.token.tokenAddress].firstBlock;
- lastBlock = acceptedTokens.tokens[acceptedToken.token.tokenAddress].lastBlock;
- limit = acceptedTokens.tokens[acceptedToken.token.tokenAddress].limit;
- }
-
- const trustIsNewer = acceptedToken.lastTrustBlock > lastBlock;
-
- acceptedTokens.tokens[acceptedToken.token.tokenAddress] = <(Token & { lastBlock: number, limit: number })>{
- ...acceptedToken.token,
- limit: trustIsNewer || !limit ? acceptedToken.limit : limit,
- firstBlock: this.min(firstBlock, acceptedToken.token.firstBlock),
- lastBlock: this.max(lastBlock, trustIsNewer ? acceptedToken.lastTrustBlock : acceptedToken.token.firstBlock)
- };
-
- acceptedTokens.firstBlock = this.min(acceptedTokens.firstBlock, acceptedToken.token.firstBlock);
- acceptedTokens.lastBlock = this.max(acceptedTokens.lastBlock, acceptedToken.lastTrustBlock);
-
- if (acceptedTokens.firstBlock > acceptedTokens.lastBlock) {
- throw new Error("acceptedTokens.firstBlock > acceptedTokens.lastBlock");
- }
- });
-
- return {
- ...safe,
- acceptedTokens
- };
- }
-
- static async addHubTransfers(safe: Safe, startBlock?: number): Promise {
- const checksumSafeAddress = RpcGateway.get().utils.toChecksumAddress(safe.safeAddress);
- const transfers = JSON.parse(JSON.stringify(safe.transfers ?? {
- rows: [],
- lastBlock: 0,
- firstBlock: 0
- }));
-
- const startAt = !transfers.lastBlock ? startBlock : transfers.lastBlock + 1;
- console.log("addHubTransfers() is starting at" + startAt)
- await new CirclesAccount(checksumSafeAddress).findHubTransfers(startAt).forEach(hubTransfer => {
- transfers.rows.push({
- _id: `${hubTransfer.blockNumber}${hubTransfer.returnValues.from}${hubTransfer.returnValues.to}`,
- type: "hub",
- symbol: "crc",
- direction: hubTransfer.returnValues.from == checksumSafeAddress ? "out" : "in",
- firstBlock: hubTransfer.blockNumber,
- from: hubTransfer.returnValues.from,
- to: hubTransfer.returnValues.to,
- amount: hubTransfer.returnValues.amount
- });
- transfers.firstBlock = this.min(transfers.firstBlock, hubTransfer.blockNumber);
- transfers.lastBlock = this.max(transfers.lastBlock, hubTransfer.blockNumber);
- });
-
- transfers.rows = transfers.rows.sort((a, b) =>
- a.firstBlock > b.firstBlock ? -1 : a.firstBlock < b.firstBlock ? 1 : 0);
-
- return {
- ...safe,
- transfers: transfers
- }
- }
-
- static tokenEvents(safe:Safe) : Observable {
- if (!safe.token?.tokenAddress) {
- throw new Error(`The safe.token.tokenAddress must be set.`)
- }
- const token = new CirclesToken(safe.token.tokenAddress, safe.safeAddress, safe.token.firstBlock);
- const sub = new Subject();
- const tokensByAddress = {
- ...safe.acceptedTokens.tokens,
- ...{
- [safe.token.tokenAddress]: safe.token
- }
- };
- token.subscribeToTransactions(sub, safe.safeAddress, tokensByAddress, Object.keys(safe.acceptedTokens.tokens).concat(safe.token.tokenAddress && safe.token.tokenAddress !== "0x00" ? [safe.token.tokenAddress] : []))
-
- return sub;
- }
-
- static async trustEvents(safe:Safe) : Promise> {
- if (!safe.safeAddress) {
- throw new Error(`The safe.safeAddress must be set.`)
- }
- const account = new CirclesAccount(safe.safeAddress);
- return account.subscribeToTrustEvents(await RpcGateway.get().eth.getBlockNumber());
- }
-
- static async addDirectTransfers(
- safe: Safe,
- startBlock?: number,
- progressCallback?:(progress:{count:number, current:number}) => void,
- tokenList?:string[],
- filterPredicate?:(transfer:Transfer) => boolean): Promise {
- if (!safe.acceptedTokens) {
- throw new Error(`The 'acceptedTokens' property must be set.`)
- }
-
- const checksumSafeAddress = RpcGateway.get().utils.toChecksumAddress(safe.safeAddress);
- const transfers = JSON.parse(JSON.stringify(safe.transfers ?? {
- rows: [],
- lastBlock: 0,
- firstBlock: 0
- }));
-
- let tokenAddresses = tokenList ?? [safe.token.tokenAddress];
- let current = 0;
- for (let tokenAddress of tokenAddresses) {
- current++;
- let token = safe.acceptedTokens.tokens[tokenAddress];
- if (!token && tokenAddress === safe.token.tokenAddress) {
- token = {...safe.token, limit: 100, lastBlock: safe.token.firstBlock};
- }
- console.log(`Direct transfers of token (${tokenAddress}) via web3 ..`);
-
- const lastDirectTransferBlock = safe.transfers?.rows.filter(o => o.type === "direct").reduce((p,c) => c.firstBlock > (p ?? 0) ? c.firstBlock : (p ?? 0), undefined)
- const startAt = !lastDirectTransferBlock ? (startBlock ?? token.firstBlock) : lastDirectTransferBlock + 1;
- console.log("addDirectTransfers() is starting at" + startAt)
- await new Erc20Token(RpcGateway.get(), tokenAddress)
- .findTransfers(checksumSafeAddress, startAt)
- .forEach(directTransfer => {
- const newTransfer = {
- _id: `${directTransfer.blockNumber}${directTransfer.returnValues.from}${directTransfer.returnValues.to}`,
- type: "direct",
- symbol: "crc",
- direction: directTransfer.returnValues.from == checksumSafeAddress ? "out" : "in",
- firstBlock: directTransfer.blockNumber,
- from: directTransfer.returnValues.from,
- to: directTransfer.returnValues.to,
- amount: directTransfer.returnValues.value,
- token: directTransfer.token.address
- }
-
- if (!filterPredicate || filterPredicate(newTransfer)) {
- transfers.rows.push(newTransfer);
- }
-
- transfers.firstBlock = this.min(transfers.firstBlock, directTransfer.blockNumber);
- transfers.lastBlock = this.max(transfers.lastBlock, directTransfer.blockNumber);
- // Update the 'first/lastBlock' of the transferred 'acceptedToken'
- const t = safe.acceptedTokens.tokens[directTransfer.token.address]
- if (t) {
- t.firstBlock = this.min(t.firstBlock, directTransfer.blockNumber);
- t.lastBlock = this.max(t.lastBlock, directTransfer.blockNumber);
- }
- });
- if (progressCallback) {
- progressCallback({
- count:tokenAddresses.length,
- current:current
- });
- }
- console.log(`Direct transfers of token (${tokenAddress}) via web3 .. Done`,);
- }
-
- transfers.rows = transfers.rows.sort((a, b) =>
- a.firstBlock > b.firstBlock ? -1 : a.firstBlock < b.firstBlock ? 1 : 0);
-
- return {
- ...safe,
- transfers: transfers
- }
- }
-
- static max(current: number | undefined, candidate: number): number {
- return !current ? candidate : Math.max(current, candidate);
- }
-
- static min(current: number | undefined, candidate: number): number {
- return !current ? candidate : Math.min(current, candidate);
- }
-
- static async addContacts(safe: Safe, startBlock?: number): Promise {
- const checksumSafeAddress = RpcGateway.get().utils.toChecksumAddress(safe.safeAddress);
- const startAt = !safe.trustRelations?.lastBlock ? startBlock : safe.trustRelations.lastBlock + 1;
- console.log("addContacts() is starting at" + startAt)
- const trustEvents = await this.readTrustEvents(checksumSafeAddress, startAt);
- const sortedAsc = trustEvents.sort((a, b) =>
- a.blockNumber > b.blockNumber ? 1 : a.blockNumber < b.blockNumber ? -1 : 0);
-
- const trustRelations = sortedAsc.reduce((p, c) => {
- let trustGiver: string, trustReceiver: string;
- let trustLimit: number = parseInt(c.returnValues.limit);
- if (c.returnValues.user == checksumSafeAddress) {
- // "safeAddress" is the trust-receiver
- trustGiver = c.returnValues.canSendTo;
- const firstBlock = this.min(p.trustedBy[trustGiver]?.firstBlock, c.blockNumber);
- const lastBlock = this.max(p.trustedBy[trustGiver]?.lastBlock, c.blockNumber);
- p.trustedBy[trustGiver] = {
- _id: `${lastBlock}${trustGiver}${safe.safeAddress}`,
- safeAddress: trustGiver,
- firstBlock: firstBlock,
- lastBlock: lastBlock,
- limit: p.trustedBy[trustGiver]?.lastBlock > c.blockNumber ? p.trustedBy[trustGiver]?.limit : trustLimit
- };
- } else {
- // "safeAddress" is the trust-giver
- trustReceiver = c.returnValues.user;
- const firstBlock = this.min(p.trusting[trustReceiver]?.firstBlock, c.blockNumber);
- const lastBlock = this.max(p.trusting[trustReceiver]?.lastBlock, c.blockNumber);
- p.trusting[trustReceiver] = {
- _id: `${lastBlock}${safe.safeAddress}${trustReceiver}`,
- safeAddress: trustReceiver,
- firstBlock: firstBlock,
- lastBlock: lastBlock,
- limit: p.trusting[trustReceiver]?.lastBlock > c.blockNumber ? p.trusting[trustReceiver]?.limit : trustLimit
- };
- }
- p.firstBlock = this.min(p.firstBlock, c.blockNumber);
- p.lastBlock = this.max(p.lastBlock, c.blockNumber);
-
- return p;
- }, {
- safeAddress: safe.safeAddress,
- firstBlock: safe?.firstBlock ?? 0,
- lastBlock: safe?.lastBlock ?? 0,
- mutualTrusts: safe.trustRelations?.mutualTrusts ?? {},
- trusting: safe.trustRelations?.trusting ?? {},
- trustedBy: safe.trustRelations?.trustedBy ?? {},
- untrusted: safe.trustRelations?.untrusted ?? {}
- });
-
- Object.keys(trustRelations.trusting).forEach(trustingKey => {
- if (trustRelations.trusting[trustingKey]?.limit === 0) {
- trustRelations.untrusted[trustingKey] = trustRelations.trusting[trustingKey];
- trustRelations.trusting[trustingKey].hide = true;
- }
- });
- Object.keys(trustRelations.trustedBy).forEach(trustingKey => {
- if (trustRelations.trustedBy[trustingKey]?.limit === 0)
- trustRelations.trustedBy[trustingKey].hide = true;
- });
-
- const pairs: {[safeAddress:string]: {
- _id:string,
- trusting: TrustObject|null,
- trustedBy: TrustObject|null
- }} = {};
-
- Object.values(trustRelations.trustedBy).forEach(o => {
- if (!pairs[o.safeAddress]) {
- pairs[o.safeAddress] = {
- _id:"",
- trusting: null,
- trustedBy: null
- };
- }
- if (o.limit > 0) {
- pairs[o.safeAddress]._id += o._id;
- pairs[o.safeAddress].trustedBy = o;
- }
- })
- Object.values(trustRelations.trusting).forEach(o => {
- if (!pairs[o.safeAddress]) {
- pairs[o.safeAddress] = {
- _id:"",
- trusting: null,
- trustedBy: null
- };
- }
- if (o.limit > 0) {
- pairs[o.safeAddress]._id += o._id;
- pairs[o.safeAddress].trusting = o;
- }
- })
-
- trustRelations.mutualTrusts = Object.values(pairs).filter(o => o.trusting && o.trustedBy).reduce((p,c) => {
- p[c.trusting.safeAddress] = c;
-
- if (trustRelations.trustedBy[c.trusting.safeAddress]) {
- trustRelations.trustedBy[c.trusting.safeAddress].hide = true;
- }
- if (trustRelations.trusting[c.trusting.safeAddress]) {
- trustRelations.trusting[c.trusting.safeAddress].hide = true;
- }
- return p;
- },{});
-
- return {
- ...safe,
- trustRelations: {
- untrusted: trustRelations.untrusted,
- mutualTrusts: trustRelations.mutualTrusts,
- firstBlock: trustRelations.firstBlock,
- lastBlock: trustRelations.lastBlock,
- trusting: trustRelations.trusting,
- trustedBy: trustRelations.trustedBy
- }
- };
- }
-
- private static async readTrustEvents(safeAddress: string, startBlock?: number): Promise {
- const contacts: BlockchainEvent[] = [];
- await new CirclesAccount(safeAddress).findTrustEvents(startBlock).forEach(contact => {
- contacts.push(contact);
- });
- return contacts;
- }
-}
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/circles/types.ts b/shell/src/dapps/o-banking/data/circles/types.ts
deleted file mode 100644
index 91283fc83..000000000
--- a/shell/src/dapps/o-banking/data/circles/types.ts
+++ /dev/null
@@ -1,97 +0,0 @@
-export type Token = {
- _id: string;
- tokenAddress: string;
- tokenOwner: string;
- firstBlock: number;
- balance?: string;
- limit?: number;
- ownerProfile?: {
- displayName: string;
- avatarUrl?: string;
- };
-};
-
-export type Transfer = {
- _id: string;
- direction: "in" | "out";
- symbol: "crc" | "xdai";
- type: "hub" | "direct";
- token?: string;
- time?: number;
- firstBlock: number;
- lastBlock?: number;
- from: string;
- fromProfile: {
- displayName: string;
- avatarUrl: string;
- };
- to: string;
- toProfile: {
- displayName: string;
- avatarUrl: string;
- };
- amount: string;
- children?: Transfer[];
-};
-
-export type TrustObject = {
- _id: string;
- hide?: boolean;
- safeAddress: string;
- firstBlock: number;
- lastBlock: number;
- limit: number;
- profile?: {
- displayName: string;
- avatarUrl: string;
- };
- type?: String;
-};
-
-export type Safe = {
- safeAddress: string;
- ownerAddress?: string;
- firstBlock?: number;
- lastBlock?: number;
- token?: Token;
- balance?: string;
- xDaiBalance?: string;
- accountxDai?: string;
- trustRelations?: {
- firstBlock: number;
- lastBlock: number;
- mutualTrusts: {
- [safeAddress: string]: {
- id: string;
- trusting: TrustObject;
- trustedBy: TrustObject;
- };
- };
- trustedBy: {
- [trustGiver: string]: TrustObject;
- };
- trusting: {
- [trustReceiver: string]: TrustObject;
- };
- untrusted: {
- [address: string]: TrustObject;
- };
- };
- acceptedTokens?: {
- firstBlock: number;
- lastBlock: number;
- tokens: {
- [tokenAddress: string]: Token & { lastBlock: number; limit: number };
- };
- };
- transfers?: {
- firstBlock: number;
- lastBlock: number;
- rows: Transfer[];
- };
- ui?: {
- loadingPercent?: number;
- loadingText?: string;
- error?: Error;
- };
-};
diff --git a/shell/src/dapps/o-banking/data/emptySafe.ts b/shell/src/dapps/o-banking/data/emptySafe.ts
deleted file mode 100644
index da6c3ef62..000000000
--- a/shell/src/dapps/o-banking/data/emptySafe.ts
+++ /dev/null
@@ -1,39 +0,0 @@
-import {Safe} from "./circles/types";
-
-export const emptySafe: Safe = {
- safeAddress: "0x00",
- balance: "0",
- ui: {
- loadingPercent: -1,
- loadingText: "No safe connected",
- error: undefined
- },
- transfers: {
- firstBlock: 0,
- lastBlock: 0,
- rows: []
- },
- token: {
- _id: "",
- tokenAddress: "0x00",
- balance: "0",
- tokenOwner: "0x00",
- firstBlock: 0
- },
- acceptedTokens: {
- tokens: {},
- lastBlock: 0,
- firstBlock: 0
- },
- lastBlock: 0,
- firstBlock: 0,
- trustRelations: {
- trustedBy: {},
- trusting: {},
- mutualTrusts: {},
- untrusted: {},
- lastBlock: 0,
- firstBlock: 0
- },
- ownerAddress: "0x00"
-};
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/loadProfileByProfileId.ts b/shell/src/dapps/o-banking/data/loadProfileByProfileId.ts
deleted file mode 100644
index 6a16cfa74..000000000
--- a/shell/src/dapps/o-banking/data/loadProfileByProfileId.ts
+++ /dev/null
@@ -1,31 +0,0 @@
-import {ProfilesDocument} from "../../o-passport/data/api/types";
-import {Profile} from "./api/types";
-import {ApiProfile} from "./apiProfile";
-
-export async function loadProfileByProfileId(profileId: number) : Promise {
- const apiClient = await window.o.apiClient.client.subscribeToResult();
- const result = await apiClient.query({
- query: ProfilesDocument,
- variables: {
- id: profileId,
- },
- });
- if (result.errors) {
- throw new Error(
- `Couldn't load a profile with id '${profileId}': ${JSON.stringify(
- result.errors
- )}`
- );
- }
-
- const apiProfile: Profile =
- result.data.profiles && result.data.profiles.length
- ? result.data.profiles[0]
- : undefined;
-
- if (!apiProfile) {
- throw new Error(`Couldn't find a profile with id '${profileId}'.`);
- }
-
- return apiProfile;
-}
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/data/loadProfileBySafeAddress.ts b/shell/src/dapps/o-banking/data/loadProfileBySafeAddress.ts
deleted file mode 100644
index 513eb1ec9..000000000
--- a/shell/src/dapps/o-banking/data/loadProfileBySafeAddress.ts
+++ /dev/null
@@ -1,65 +0,0 @@
-import gql from "graphql-tag";
-import {ApiProfile} from "./apiProfile";
-
-export async function loadProfileBySafeAddress(safeAddress: string) : Promise {
- // 1. Try to find a profile via the api
- const apiClient = await window.o.apiClient.client.subscribeToResult();
- const result = await apiClient.query({
- query: gql`
- query profiles($circlesAddress: [String!]) {
- profiles(query: { circlesAddress: $circlesAddress }) {
- id
- circlesAddress
- circlesSafeOwner
- firstName
- lastName
- avatarUrl
- avatarCid
- avatarMimeType
- dream
- country
- }
- }
- `,
- variables: {
- circlesAddress: [safeAddress],
- },
- });
- if (result.errors) {
- throw new Error(
- `Couldn't load a profile with safeAddress '${safeAddress}': ${JSON.stringify(
- result.errors
- )}`
- );
- }
-
- const profile =
- result.data.profiles && result.data.profiles.length
- ? result.data.profiles[0]
- : undefined;
- if (profile) {
- return profile;
- }
-
- // 2. Try to find a profile via circles garden
- const requestUrl = `https://api.circles.garden/api/users/?address[]=${safeAddress}`;
- const gardenResult = await fetch(requestUrl);
- if (gardenResult && gardenResult.status == 200) {
- const resultJson = await gardenResult.json();
- const profile =
- resultJson.data && resultJson.data.length
- ? resultJson.data[0]
- : undefined;
- return {
- circlesAddress: safeAddress,
- firstName: profile ? profile.username : "",
- avatarUrl: profile ? profile.avatarUrl : undefined,
- };
- }
-
- // 3. No profile found
- return {
- circlesAddress: safeAddress,
- firstName: "",
- };
-}
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/init.ts b/shell/src/dapps/o-banking/init.ts
index bf42353ef..63730795f 100644
--- a/shell/src/dapps/o-banking/init.ts
+++ b/shell/src/dapps/o-banking/init.ts
@@ -1,406 +1,33 @@
-import {me, Profile} from "../../shared/stores/me";
-import {Subscription} from "rxjs";
-import {Safe} from "./data/circles/types";
-import {RpcGateway} from "@o-platform/o-circles/dist/rpcGateway";
-import {emptySafe} from "./data/emptySafe";
-import {Queries} from "./data/circles/queries";
-import {augmentSafeWithProfiles} from "./data/augmentSafeWithProfiles";
-import {Erc20Token} from "@o-platform/o-circles/dist/token/erc20Token";
-import {BN} from "ethereumjs-util";
-import {showToast} from "../../shared/toast";
-import {PlatformEvent} from "@o-platform/o-events/dist/platformEvent";
-import {DelayedTrigger} from "@o-platform/o-utils/dist/delayedTrigger";
-import {augmentSafeWithTime} from "./data/augmentSafeWithTime";
-import {GetUbiContextData} from "./processes/getUbi";
-import {getUBIService} from "./processes/getUBIService";
-import {ProcessContext} from "@o-platform/o-process/dist/interfaces/processContext";
-import {HUB_BLOCK} from "@o-platform/o-circles/dist/consts";
-import {ProgressSignal} from "@o-platform/o-events/dist/signals/progressSignal";
-import {ShellEvent} from "@o-platform/o-process/dist/events/shellEvent";
+import { Subscription } from "rxjs";
+import { PlatformEvent } from "@o-platform/o-events/dist/platformEvent";
+import { Profile } from "../../shared/api/data/types";
-let _currentSafe: Safe | null = emptySafe;
-let loading = false;
let profile: Profile | undefined;
-let blockChainEventsSubscription: Subscription | null;
-
-export function tryGetCurrentSafe() {
- return _currentSafe;
-}
-
-function publishRefreshEvent(safe:Safe) {
- window.o.publishEvent({
- type: "shell.refresh",
-
-
- dapp: "banking:1",
- data: safe
- });
-}
-
-type LoadParamsFlags = {
- addOwnToken?: boolean,
- addHubTransfers?: boolean,
- addContacts?: boolean,
- addAcceptedTokens?: boolean,
- addBalances?: boolean,
- addDirectTransfers?: boolean
-}
-type LoadParams = {
- profile: Profile,
- safe: Safe,
- tokenList: string[],
- flags: LoadParamsFlags
-}
-
-async function getUBI(safeAddress:string) : Promise {
- try {
- await getUBIService(> {
- data: {
- safeAddress,
- privateKey: localStorage.getItem("circlesKey")
- }
- })
- localStorage.setItem("lastUBI", new Date().toJSON());
- } catch (e) {
- console.error("Couldn't retrieve your UBI.")
- }
-}
-
-async function checkUBI(safeAddress:string) : Promise {
- const lastUBIDateString = localStorage.getItem("lastUBI");
- if (!lastUBIDateString) {
- return await getUBI(safeAddress);
- } else {
- const date = Date.parse(lastUBIDateString);
- if (date < Date.now() - 24*60*60*1000) {
- return await getUBI(safeAddress);
- }
- }
-}
-
-async function load(args: LoadParams): Promise {
- if (loading) {
- return;
- }
- loading = true;
-
- return new Promise(async (resolve, reject) => {
- try {
- if (!RpcGateway.get().utils.isAddress(profile.circlesAddress ?? "")) {
- localStorage.removeItem("safe");
- window.o.publishEvent({
- type: "shell.refresh",
- dapp: "banking:1",
- data: emptySafe
- });
- _currentSafe = emptySafe;
- return;
- }
-
- let safe: Safe = args.safe ?? {
- safeAddress: profile.circlesAddress,
- ui: {
- loadingPercent: 0
- }
- };
-
- let _watchLoadingPercent = safe.ui?.loadingPercent;
- const timeoutHandle = setInterval(() => {
- console.log("RPC watchdog: checking for progress ..")
- if (safe?.ui?.loadingPercent === 0 || safe?.ui?.loadingPercent === null || safe?.ui?.loadingPercent === undefined) {
- console.log("RPC watchdog: checking for progress .. Process got stuck. Sending error ..")
- clearInterval(timeoutHandle);
- reject(new Error("slow_provider"));
- return;
- }
- if (safe.ui?.loadingPercent && safe.ui?.loadingPercent == _watchLoadingPercent) {
- console.log("RPC watchdog: checking for progress .. Process got stuck. Sending error ..")
- clearInterval(timeoutHandle);
- reject(new Error("slow_provider"));
- return;
- } else {
- console.log("RPC watchdog: checking for progress .. Process is moving. Leaving.")
- _watchLoadingPercent = safe.ui?.loadingPercent;
- }
- }, 5000);
-
- if (args.flags.addOwnToken || args.flags.addOwnToken === undefined) {
- safe = await Queries.addOwnToken(safe);
- console.log(new Date().getTime() + ": " + "Token via web3:", JSON.stringify(safe, null, 2));
- }
-
- if (args.flags.addHubTransfers || args.flags.addHubTransfers === undefined) {
- safe.ui.loadingText = "Loading hub transfers ..";
- publishRefreshEvent(safe);
- _currentSafe = safe;
-
- safe = await Queries.addHubTransfers(safe, safe.token?.firstBlock ?? HUB_BLOCK.toNumber());
- const hubTransferCount = safe.transfers.rows.length;
- console.log(new Date().getTime() + ": " + `Added ${hubTransferCount} hub transfers.`)
- }
-
- if (args.flags.addContacts || args.flags.addContacts === undefined) {
- safe.ui.loadingPercent = 5;
- safe.ui.loadingText = "Loading trust connections ..";
- publishRefreshEvent(safe);
- _currentSafe = safe;
-
- try {
- // TODO: Fix properly instead of just catching the error
- safe = await Queries.addContacts(safe);
- console.log(new Date().getTime() + ": " + `Added ${Object.keys(safe.trustRelations.trusting).length + Object.keys(safe.trustRelations.trustedBy).length} trust relations.`)
- } catch (e) {
- console.error(e);
- }
- }
- safe.ui.loadingPercent = 18;
-
- if (args.flags.addAcceptedTokens || args.flags.addAcceptedTokens === undefined) {
- safe.ui.loadingText = "" +
- "Loading accepted tokens ..";
- publishRefreshEvent(safe);
- _currentSafe = safe;
-
- safe = await Queries.addAcceptedTokens(safe);
- augmentSafeWithProfiles(safe);
- augmentSafeWithTime(safe);
- console.log(new Date().getTime() + ": " + `Added ${Object.keys(safe.acceptedTokens.tokens).length} accepted tokens.`)
- }
-
- safe.ui.loadingPercent = 22;
-
- if (args.flags.addBalances || args.flags.addBalances === undefined) {
- safe.ui.loadingText = "Loading balances ..";
- publishRefreshEvent(safe);
- _currentSafe = safe;
-
- safe = await Queries.addxDaiBalances(safe);
- safe = await Queries.addTokenBalances(safe);
- safe.token.balance = (await new Erc20Token(RpcGateway.get(), safe.token.tokenAddress).getBalanceOf(safe.safeAddress)).toString();
- console.log(new Date().getTime() + ": " + `Added balances to ${Object.keys(safe.acceptedTokens.tokens).length} tokens.`)
- publishRefreshEvent(safe);
- _currentSafe = safe;
- }
-
- const totalBalance = Object.keys(safe.acceptedTokens?.tokens ?? {}).reduce((p: BN, c: string) => p.add(new BN(safe.acceptedTokens.tokens[c].balance)), new BN("0")).add(new BN(safe.token.balance));
- const totalBalanceStr = totalBalance.toString();
- safe.balance = parseFloat(RpcGateway.get().utils.fromWei(totalBalanceStr, "ether")).toFixed(2);
-
- if (args.flags.addDirectTransfers || args.flags.addDirectTransfers === undefined) {
- safe.ui.loadingPercent = 26;
- safe.ui.loadingText = "Loading direct transfers ..";
- publishRefreshEvent(safe);
- _currentSafe = safe;
-
- const lastProgress = safe.ui.loadingPercent;
- const remainingPercents = 100 - lastProgress;
- safe = await Queries.addDirectTransfers(
- safe,
- undefined,
- progress => {
- safe.ui.loadingPercent = lastProgress + (remainingPercents / progress.count) * progress.current;
- publishRefreshEvent(safe);
- _currentSafe = safe;
- },
- args.tokenList,
- transfer => transfer.from == "0x0000000000000000000000000000000000000000"
- );
- console.log(new Date().getTime() + ": " + `Added ${safe.transfers.rows.length - safe.transfers?.rows?.length ?? 0} direct transfers.`);
- }
-
- safe.ui.loadingPercent = 100;
- publishRefreshEvent(safe);
- _currentSafe = safe;
- safe.ui.loadingPercent = undefined;
- safe.ui.loadingText = undefined;
-
- clearInterval(timeoutHandle);
-
- await augmentSafeWithTime(safe);
- localStorage.setItem("safe", JSON.stringify(safe));
-
- await augmentSafeWithProfiles(safe);
- publishRefreshEvent(safe);
- _currentSafe = safe;
-
- await subscribeChainEvents(safe);
-
- if (_currentSafe && _currentSafe.safeAddress !== emptySafe.safeAddress) {
- checkUBI(_currentSafe.safeAddress);
- }
-
- return resolve(safe);
- } catch (e) {
- localStorage.removeItem("safe");
- reject(e);
- } finally {
- loading = false;
- }
- });
-}
-
let shellEventSubscription: Subscription | undefined;
-let unsubscribeMe: () => void;
-export function init() {
+export async function init() {
if (shellEventSubscription) {
shellEventSubscription.unsubscribe();
}
- unsubscribeMe = me.subscribe(async profileOrNull => {
- profile = profileOrNull;
- if (profileOrNull && RpcGateway.get().utils.isAddress(profileOrNull.circlesAddress ?? "")) {
- for (let i = 0; i < RpcGateway.gateways.length; i++) {
- try {
- await update(undefined, {});
- return;
- } catch (e) {
- if (e.message === "slow_provider") {
- loading = false;
- RpcGateway.rotateProvider();
- console.warn("The provider took too long to answer. Retrying with a different provider ...");
- } else {
- throw e;
- }
- }
+ shellEventSubscription = window.o.events.subscribe(
+ async (
+ event: PlatformEvent & {
+ profile: Profile;
}
- }
-
- // TODO: When we reach this point all requests failed. Show an error to the user.
- showToast("error", "The connection to the RPC gateway was lost and we weren't " +
- "able to restore it in time. Please refresh the page to give it another try.");
-
- localStorage.removeItem("safe");
- });
-
- shellEventSubscription = window.o.events.subscribe(async (event: PlatformEvent & {
- profile: Profile
- }) => {
- if (event.type == "shell.loggedOut") {
- localStorage.removeItem("safe");
- localStorage.removeItem("circlesAddress");
- localStorage.removeItem("circlesKey");
- localStorage.removeItem("lastUBI");
- profile = null;
- window.o.publishEvent({
- type: "shell.refresh",
- dapp: "banking:1",
- data: null
- });
- _currentSafe = null;
- return;
- } else if (event.type === "circles.web3providerChanged") {
- if (!loading) {
- await subscribeChainEvents(_currentSafe);
+ ) => {
+ if (event.type == "shell.loggedOut") {
+ localStorage.removeItem("safe");
+ localStorage.removeItem("circlesAddress");
+ localStorage.removeItem("circlesKey");
+ localStorage.removeItem("lastUBI");
+ profile = null;
+ return;
}
}
- });
+ );
return function stop() {
shellEventSubscription.unsubscribe();
- unsubscribeMe();
- if (blockChainEventsSubscription) {
- blockChainEventsSubscription.unsubscribe();
- }
- }
-}
-
-async function subscribeChainEvents(safe: Safe) {
- if (blockChainEventsSubscription) {
- blockChainEventsSubscription.unsubscribe();
- }
- let onEventUpdateTrigger = new DelayedTrigger(500, async (tokenList: string[]) => {
- for (let i = 0; i < RpcGateway.gateways.length; i++) {
- try {
- _currentSafe = await update(tokenList, {
- addAcceptedTokens: false,
- addContacts: true,
- addDirectTransfers: true,
- addHubTransfers: true,
- addOwnToken: false,
- addBalances: true
- });
- return;
- } catch (e) {
- if (e.message === "slow_provider") {
- loading = false;
- RpcGateway.rotateProvider();
- console.warn("The provider took too long to answer. Retrying with a different provider ...");
- } else {
- throw e;
- }
- }
- }
-
- // TODO: When we reach this point all requests failed. Show an error to the user.
- showToast("error", "The connection to the RPC gateway was lost and we weren't " +
- "able to restore it in time. Please refresh the page to give it another try.");
-
- });
-
- if (safe && RpcGateway.get().utils.isAddress(safe.safeAddress)) {
- blockChainEventsSubscription = Queries.tokenEvents(safe).subscribe((event: any) => {
- console.log("NEW EVENT:", event);
- onEventUpdateTrigger.trigger(/*[event.token]*/);
- });
- (await Queries.trustEvents(safe)).subscribe((event:any) => {
- console.log("NEW EVENT:", event);
- onEventUpdateTrigger.trigger(/*[event.token]*/);
- });
- } else {
- console.warn("safe is not set supplied.")
- }
-}
-
-async function update(tokenList: string[]|undefined, flags:LoadParamsFlags): Promise {
- if (!profile) {
- return;
- }
- if (!_currentSafe || _currentSafe.safeAddress === emptySafe.safeAddress) {
- _currentSafe = await tryRestoreCache();
- }
-
- _currentSafe = await load({
- safe: _currentSafe,
- tokenList: tokenList,
- profile: profile,
- flags: flags
- });
-
- return _currentSafe;
+ };
}
-
-async function tryRestoreCache() {
- const cachedSafeJson = localStorage.getItem("safe");
- if (!cachedSafeJson) {
- return;
- } else {
- try {
- const safe = JSON.parse(cachedSafeJson);
- window.o.publishEvent({
- type: "shell.refresh",
- dapp: "banking:1",
- data: safe
- });
- _currentSafe = safe;
- await augmentSafeWithProfiles(safe);
- window.o.publishEvent({
- type: "shell.refresh",
- dapp: "banking:1",
- data: safe
- });
- _currentSafe = safe;
- return safe;
- } catch (e) {
- console.error("An error occurred while restoring or updating the cached safe:", e);
- localStorage.removeItem("safe");
- window.o.publishEvent({
- type: "shell.refresh",
- dapp: "banking:1",
- data: emptySafe
- });
- _currentSafe = emptySafe;
- return undefined;
- }
- }
-}
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/molecules/TrustChangeConfirmation.svelte b/shell/src/dapps/o-banking/molecules/TrustChangeConfirmation.svelte
new file mode 100644
index 000000000..83c28b07c
--- /dev/null
+++ b/shell/src/dapps/o-banking/molecules/TrustChangeConfirmation.svelte
@@ -0,0 +1,35 @@
+
+
+{#if _context.data && _context.data.profile}
+
+
+
+
+
+ {#if _context.data.trustLimit == 100}
+ You trust {_context.data.profile[0].displayName} now
+ {:else}
+ You removed your trust to {_context.data.profile[0].displayName}
+ {/if}
+
+
+
+
+{/if}
diff --git a/shell/src/dapps/o-banking/pages/AssetDetail.svelte b/shell/src/dapps/o-banking/pages/AssetDetail.svelte
deleted file mode 100644
index d4cde6a0d..000000000
--- a/shell/src/dapps/o-banking/pages/AssetDetail.svelte
+++ /dev/null
@@ -1,130 +0,0 @@
-
-
-
-
-
- {#if !$mySafe || !$mySafe.token || !$mySafe.acceptedTokens}
-
- {:else if params && params.symbol == "xdai"}
-
-
-
- WHAT IS THIS?
-
-
-
- Your xDAI is distributed between two accounts.
- On the safeowner account you have xDai to pay your transaction fees.
-
- 0,25xDAI gives you 1000+ transactions.
- On the safe account you store your invite credits, that
- you can use to onboard other people.
- For each invite your need a minimum of 0,10xDAI..
-
-
-
-
- {#each [accountxDai, safexDai].sort( (a, b) => (parseFloat(a.balance) > parseFloat(b.balance) ? -1 : parseFloat(a.balance) < parseFloat(b.balance) ? 1 : 0) ) as token}
-
- {/each}
- {:else}
- {#each ($mySafe.token ? [$mySafe.token] : []).concat(tokens) as token}
- {#if token && token.balance > 0}
-
- {/if}
- {/each}
- {/if}
-
diff --git a/shell/src/dapps/o-banking/pages/Assets.svelte b/shell/src/dapps/o-banking/pages/Assets.svelte
index ed26b7933..975c38d9a 100644
--- a/shell/src/dapps/o-banking/pages/Assets.svelte
+++ b/shell/src/dapps/o-banking/pages/Assets.svelte
@@ -1,132 +1,165 @@
+ return copy;
+ });
+
+ erc20DisplayBalances = erc20DisplayBalances
+ .sort((a, b) => {
+ const bnA =
+ a.token_symbol == "EURS" ? new BN(a.token_balance).mul(new BN("1000000000000000000")) : new BN(a.token_balance);
+ const bnB =
+ b.token_symbol == "EURS" ? new BN(b.token_balance).mul(new BN("1000000000000000000")) : new BN(b.token_balance);
+ return bnA.gt(bnB) ? -1 : bnA.lt(bnB) ? 1 : 0;
+ })
+ .map((o) => {
+ if (o.token_symbol == "EURS") {
+ return {
+ ...o,
+ token_balance: (o.token_balance = (parseFloat(o.token_balance) / 100).toFixed(2)),
+ };
+ } else {
+ return {
+ ...o,
+ token_balance: (o.token_balance = parseFloat(
+ RpcGateway.get().utils.fromWei(o.token_balance, "ether")
+ ).toFixed(2)),
+ };
+ }
+ });
-
+ updateXdaiBalance().then((o) => {
+ if (loading) {
+ loading = false;
+ }
+ });
+}
-
-
-
-
- WHAT IS THIS?
-
+loading = false;
+
-
- Since everyone has their own personalized Circles money, you will always
- only be able to receive and hold Circles of those you directly trust.
- To see which personalized Circles you are currently holding,
- click onto the Circles Card.
- xDai is the currency that is used to invite others and pay
- transaction fees.
-
-
-
+
- {#if !$mySafe || !$mySafe.token || !$mySafe.acceptedTokens}
-
-
+
+
{:else}
{#each [circles, xdai] as token}
+ symbol="{token.symbol}"
+ title="{token.title}"
+ balance="{token.balance}"
+ variety="{token.variety}"
+ description="{token.description}"
+ details="{token.details}" />
{/each}
- {/if}
-
+ {#each erc20DisplayBalances as token}
+ {#if token}
+
+
+
+ {/if}
{/each}
{/if}
--->
-
diff --git a/shell/src/dapps/o-banking/pages/CrcDetail.svelte b/shell/src/dapps/o-banking/pages/CrcDetail.svelte
new file mode 100644
index 000000000..d6667ade4
--- /dev/null
+++ b/shell/src/dapps/o-banking/pages/CrcDetail.svelte
@@ -0,0 +1,74 @@
+
+
+
+
+
+
+ {#if loading}
+
+ {:else}
+ {#each balances as token}
+ {#if token && token.token_balance > 0}
+
+
+
+ {/if}
+ {/each}
+ {/if}
+
diff --git a/shell/src/dapps/o-banking/pages/FindMySafe.svelte b/shell/src/dapps/o-banking/pages/FindMySafe.svelte
deleted file mode 100644
index b3f02b986..000000000
--- a/shell/src/dapps/o-banking/pages/FindMySafe.svelte
+++ /dev/null
@@ -1,69 +0,0 @@
-
-Use this page to recover your safe address from your seedphrase.
-Seedphrase:
-Recover
-
- {!safeAddress ? "" : safeAddress}
-
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/pages/Graph.svelte b/shell/src/dapps/o-banking/pages/Graph.svelte
deleted file mode 100644
index f7fd20a3e..000000000
--- a/shell/src/dapps/o-banking/pages/Graph.svelte
+++ /dev/null
@@ -1,11 +0,0 @@
-
-
-
-
-{#if $mySafe}
-
-{/if}
diff --git a/shell/src/dapps/o-banking/pages/Profile.svelte b/shell/src/dapps/o-banking/pages/Profile.svelte
deleted file mode 100644
index 8addc1127..000000000
--- a/shell/src/dapps/o-banking/pages/Profile.svelte
+++ /dev/null
@@ -1,667 +0,0 @@
-
-
-
-{#if isLoading}
-
-{:else}
-
- {#if !profile.safeAddress && !isMe}
-
-
-
- This citizen is waiting to be empowered by you.
-
-
- {#if $me && $me.id !== profile.id && $me.circlesAddress}
-
-
- Invite {profile.displayName} now
-
-
- {:else}
-
- {/if}
-
-
- {/if}
- {#if !profile.safeAddress && isMe}
-
-
-
-
-
-
- You're almost there.
-
-
- Copy the invite link and send it to someone who's already a
- citizen of CirclesLand:
-
-
-
-
- Copy Invite Link
-
-
-
- {inviteLink}
-
-
-
- If you don't know anybody who has Circles yet, ask nicely in our Discord if someone can invite you.
-
-
- alternatively, become a hub
-
-
-
-
-
- {/if}
-
- {#if profile && profile.safeAddress}
-
-
-
- ADDRESS
-
-
-
-
-
- {#if profile}
-
- {profile.safeAddress ? profile.safeAddress : ""}
- {/if}
-
-
-
-
-
-
- {/if}
-
-
-
- PASSION
-
-
-
-
-
- {#if profile && profile.dream}
- {profile.dream}
- {:else}
- No passion set.
- {/if}
- {#if isEditable}
- editProfile({ dream: true })}
- >
-
-
-
-
- {/if}
-
-
-
-
-
-
-
-
-
- COUNTRY
-
-
-
-
-
- {#if profile && profile.country}
- {getCountryName(profile.country)}
- {:else}
- No Country set.
- {/if}
- {#if isEditable}
- editProfile({ country: true })}
- >
-
-
-
-
- {/if}
-
-
-
-
-
-
- {#if !isMe && (profile.trusting || profile.trustedBy)}
-
-
-
TRUST
-
- {#if profile.trusting && profile.trustedBy}
-
-
-
-
-
You are trusting {profile.displayName}
- {profile.trusting}%
-
-
-
-
-
-
-
-
{profile.displayName} is trusting you {profile.trustedBy}%
-
-
- {:else if profile.trusting && !profile.trustedBy}
-
-
-
-
-
You are trusting {profile.displayName}
- {profile.trusting}%
-
-
- {:else if !profile.trusting && profile.trustedBy}
-
-
-
-
-
{profile.displayName} is trusting you
- {profile.trustedBy}%
-
-
- {/if}
-
-
-
- {/if}
- {#if !isMe && profile.safeAddress}
-
-
-
TRANSFER
-
-
- execTransfer()}>Send Money
-
-
-
-
-
-
-
- CHANGE TRUST
-
- {#if profile.trusting && profile.trusting > 0}
-
-
execUntrust()}
- >
-
-
-
- Remove trust
-
-
- {:else}
-
-
execTrust()}
- >
-
-
-
- Trust
-
-
- {/if}
-
-
- {/if}
-
-{/if}
diff --git a/shell/src/dapps/o-banking/pages/TransactionDetail.svelte b/shell/src/dapps/o-banking/pages/TransactionDetail.svelte
index e3142c1a0..976296672 100644
--- a/shell/src/dapps/o-banking/pages/TransactionDetail.svelte
+++ b/shell/src/dapps/o-banking/pages/TransactionDetail.svelte
@@ -1,282 +1,257 @@
-
-{#if transfer}
-
-
-
-
- {#if transfer.time}
- {#if dateOlderThanSevenDays(transfer.time)}
-
- {:else}
-
- {/if}
+
+
+ {#if transfer}
+
+
+
+ {transfer.direction === "in" ? "received" : "sent"}
+
+
+
+
+ {#if transfer.direction === "in"}
+ +{Currency.instance().displayAmount(
+ transfer ? (transfer.payload.value ? transfer.payload.value : transfer.payload.flow).toString() : "0",
+ transfer.timestamp,
+ "TIME_CRC",
+ transfer.payload.__typename === "Erc20Transfer" ? "erc20" : ""
+ )}
+ {:else}
+ -{Currency.instance().displayAmount(
+ transfer ? (transfer.payload.value ? transfer.payload.value : transfer.payload.flow).toString() : "0",
+ transfer.timestamp,
+ "TIME_CRC",
+ transfer.payload.__typename === "Erc20Transfer" ? "erc20" : ""
+ )}
{/if}
+
+
+
+
+
+ {#if transfer.direction === "in"}
+
+
+ {displayableName ? displayableName : ""}
+
+ {:else}
+
+
+ {displayableName ? displayableName : ""}
+
+ {/if}
+
+
+ {message && message != undefined ? message : ""}
+
+
+
+
+
-
-
{
- if (!transfer.from.startsWith("0x000")) {
- push("#/banking/trusts/" + transfer.from);
- }
- }}
- >
-
-
-
-
-
-
- {displayableFromName}
-
+
+
+
+
+
+
+
+ {Currency.instance().displayAmount(
+ transfer ? (transfer.payload.value ? transfer.payload.value : transfer.payload.flow).toString() : "0",
+ transfer.timestamp,
+ "CRC",
+ null,
+ true
+ )}
-
{
- if (!transfer.to.startsWith("0x000")) {
- push("#/banking/trusts/" + transfer.to);
- }
- }}
- >
-
-
-
-
-
-
- {transfer.toProfile
- ? transfer.toProfile.displayName
- : transfer.to}
-
+
+
+
+
+
+
+
+
+
{fromProfile.circlesAddress}
-
-
-
-
-
- TRANSACTION DETAILS
+
+
+
-
-
-
+
+
{toProfile.circlesAddress}
+
+
+
+
+
+
+
+
{transfer.block_number}
+
+
+
+
+
+
+
+
+ {transfer.transaction_hash ? transfer.transaction_hash : ""}
-
-
-{/if}
+
+ {/if}
+
diff --git a/shell/src/dapps/o-banking/pages/Transactions.svelte b/shell/src/dapps/o-banking/pages/Transactions.svelte
index d1700b97f..40ae25dd2 100644
--- a/shell/src/dapps/o-banking/pages/Transactions.svelte
+++ b/shell/src/dapps/o-banking/pages/Transactions.svelte
@@ -1,122 +1,26 @@
-
-
-
- {#if $mySafe.ui && $mySafe.ui.loadingPercent === 0}
-
-
-
-
Loading Transactions...
-
-
-
- {:else if $mySafe.ui && $mySafe.ui.error}
-
-
-
-
- An error occurred while loading the recent activities:
- {$mySafe.ui.error.message}
-
-
-
-
- {:else if $mySafe.transfers && $mySafe.transfers.rows}
- {#each $mySafe.transfers.rows as transfer}
- {#if transfer.direction === "in"}
-
- {:else}
-
- {/if}
- {/each}
- {:else}
-
-
-
-
- No recent activities
-
-
-
-
- {/if}
-
-
-
- WHAT IS THIS?
-
-
-
- This is your Circles banking account and you just got your first 50
- Circles as a welcome gift.
-
- From today on you will unconditionally receive 8 more
- Circles every day in the form of your personal universal basic income.
-
+
- Have a look around and explore the navigation buttons below, to learn more about how Circles works in detail.
-
-
-
+
+
diff --git a/shell/src/dapps/o-banking/pages/Trusts.svelte b/shell/src/dapps/o-banking/pages/Trusts.svelte
deleted file mode 100644
index 9272afe47..000000000
--- a/shell/src/dapps/o-banking/pages/Trusts.svelte
+++ /dev/null
@@ -1,160 +0,0 @@
-
-
-
-
-
- {#if !$mySafe.trustRelations || !$mySafe.trustRelations.mutualTrusts || !$mySafe.trustRelations.trusting || !$mySafe.trustRelations.trustedBy}
-
- {:else if $mySafe.ui.error}
-
-
-
-
- An error occurred while loading the recent activities:
- {$mySafe.ui.error.message}
-
-
-
-
- {:else}
- {#if Object.values($mySafe.trustRelations.mutualTrusts).length >= 1}
-
-
- {#each Object.values($mySafe.trustRelations.mutualTrusts) as mutualTrust}
-
- {/each}
- {/if}
- {#if Object.values($mySafe.trustRelations.trusting).filter((o) => !o.hide).length >= 1}
-
- {#each Object.values($mySafe.trustRelations.trusting).filter((o) => !o.hide) as trusting}
-
-
- {/each}
- {/if}
-
- {#if Object.values($mySafe.trustRelations.trustedBy).filter((o) => !o.hide && o.safeAddress.toLowerCase() !== $mySafe.safeAddress.toLowerCase()).length >= 1}
-
-
- {#each Object.values($mySafe.trustRelations.trustedBy).filter((o) => !o.hide && o.safeAddress.toLowerCase() !== $mySafe.safeAddress.toLowerCase()) as trustedBy}
-
- {/each}
- {/if}
-
- {#if Object.values($mySafe.trustRelations.untrusted).length >= 1}
-
-
- {#each Object.values($mySafe.trustRelations.untrusted) as untrusted}
-
- {/each}
- {/if}
- {/if}
-
-
-
-
-
-
-
- In CirclesLand everyone has their own personalized Circles money. You
- have "YOU" Circles and your friend Bob has "BOB" Circles.
-
- To be able to transfer Circles to someone you first need to get trusted by
- others. When you want to receive money you have to trust them back.
-
- To transact with a stranger the network will
- calculate the flow of money for you, based on your direct trust
- connections.
-
- The better you are connected the more useable your Circles become. Keep in mind to always only connect yourself with people you trust and know
- in person. To connect yourself, send your "trust link" to other citizens you know in person.
-
Learn more
-
-
-
- Copy trust link
-
-
-
-
diff --git a/shell/src/dapps/o-banking/pages/XDaiDetail.svelte b/shell/src/dapps/o-banking/pages/XDaiDetail.svelte
new file mode 100644
index 000000000..e3d30c9c5
--- /dev/null
+++ b/shell/src/dapps/o-banking/pages/XDaiDetail.svelte
@@ -0,0 +1,80 @@
+
+
+
+
+
Xdai
+
+
+ {#each balances.sort( (a, b) => (parseFloat(a.balance) > parseFloat(b.balance) ? -1 : parseFloat(a.balance) < parseFloat(b.balance) ? 1 : 0) ) as token}
+
+ {/each}
+
diff --git a/shell/src/dapps/o-banking/processes/deploySafe.ts b/shell/src/dapps/o-banking/processes/deploySafe.ts
deleted file mode 100644
index 825d592d3..000000000
--- a/shell/src/dapps/o-banking/processes/deploySafe.ts
+++ /dev/null
@@ -1,204 +0,0 @@
-import { ProcessDefinition } from "@o-platform/o-process/dist/interfaces/processManifest";
-import { ProcessContext } from "@o-platform/o-process/dist/interfaces/processContext";
-import { fatalError } from "@o-platform/o-process/dist/states/fatalError";
-import { createMachine } from "xstate";
-import {PlatformEvent} from "@o-platform/o-events/dist/platformEvent";
-import {GnosisSafeProxyFactory} from "@o-platform/o-circles/dist/safe/gnosisSafeProxyFactory";
-import {RpcGateway} from "@o-platform/o-circles/dist/rpcGateway";
-import {GNOSIS_SAFE_ADDRESS, HUB_ADDRESS, PROXY_FACTORY_ADDRESS} from "@o-platform/o-circles/dist/consts";
-import {CirclesHub} from "@o-platform/o-circles/dist/circles/circlesHub";
-import {GnosisSafeProxy} from "@o-platform/o-circles/dist/safe/gnosisSafeProxy";
-import {Web3Contract} from "@o-platform/o-circles/dist/web3Contract";
-import {BN} from "ethereumjs-util";
-import {upsertIdentity} from "../../o-passport/processes/upsertIdentity";
-import {loadProfile} from "../../o-passport/processes/identify/services/loadProfile";
-import {Profile} from "../data/api/types";
-import {UpsertProfileDocument} from "../../o-passport/data/api/types";
-import {emptySafe} from "../data/emptySafe";
-import {push} from "svelte-spa-router";
-
-export type HubSignupContextData = {
- privateKey:string;
- deployedProxy?:GnosisSafeProxy;
- profile?: Profile
-};
-
-/**
- * This is the context on which the process will work.
- * The actual fields are defined above in the 'AuthenticateContextData' type.
- * The 'AuthenticateContextData' type is also the return value of the process (see bottom for the signature).
- */
-export type HubSignupContext = ProcessContext
;
-
-/**
- * In case you want to translate the flow later, it's nice to have the strings at one place.
- */
-const strings = {
-};
-
-export const INITIAL_ACCOUNT_XDAI = new BN(RpcGateway.get().utils.toWei("0.025", "ether"));
-
-const processDefinition = (processId: string) =>
-createMachine({
- id: `${processId}:deploySafe`,
- initial: "loadProfile",
- states: {
- ...fatalError("error"),
-
- loadProfile: {
- id: "loadProfile",
- entry: [
- (ctx) => console.log(`enter: identify.loadProfile`, ctx.data),
- () => {
- window.o.publishEvent({
- type: "shell.progress",
- message: `Loading your profile ..`
- });
- }
- ],
- invoke: {
- src: async (context) => {
- context.data.profile = await loadProfile();
- },
- onDone: "#checkEntryPoint",
- onError: "#error"
- }
- },
-
- checkEntryPoint: {
- id: "checkEntryPoint",
- always:[{
- cond: () => !!localStorage.getItem("isCreatingSafe"),
- target: "deploySafe"
- },{
- cond: () => !!localStorage.getItem("fundsSafe"),
- target: "fundSafe"
- },{
- cond: () => !!localStorage.getItem("signsUpAtCircles"),
- target: "hubSignup"
- }]
- },
-
- deploySafe: {
- id: "deploySafe",
- entry: () => {
- window.o.publishEvent({
- type: "shell.progress",
- message: `Finishing your setup (deploying safe) ..`
- });
- },
- invoke: {
- src: async (context) => {
- const proxyFactory = new GnosisSafeProxyFactory(RpcGateway.get(), PROXY_FACTORY_ADDRESS, GNOSIS_SAFE_ADDRESS);
- context.data.deployedProxy = await proxyFactory.deployNewSafeProxy(context.data.privateKey);
- context.data.profile.circlesAddress = context.data.deployedProxy.address;
- },
- onDone: "#upsertIdentity",
- onError: "#error",
- },
- },
- upsertIdentity: {
- id: "upsertIdentity",
- entry: () => {
- window.o.publishEvent({
- type: "shell.progress",
- message: `Finishing your setup (connecting the safe to your profile) ..`
- });
- },
- invoke: {
- src: async (context) => {
- const apiClient = await window.o.apiClient.client.subscribeToResult();
- const result = await apiClient.mutate({
- mutation: UpsertProfileDocument,
- variables: {
- ...context.data.profile
- },
- });
-
- localStorage.removeItem("isCreatingSafe");
- localStorage.setItem("fundsSafe", "true");
-
- window.o.publishEvent({
- type: "shell.authenticated",
- profile: result.data.upsertProfile,
- });
-
- return result.data.upsertProfile;
- },
- onDone: "#fundSafe",
- onError: "#error",
- },
- },
- fundSafe: {
- id: "fundSafe",
- entry: () => {
- window.o.publishEvent({
- type: "shell.progress",
- message: `Finishing your setup (transferring xDai to your new safe) ..`
- });
- },
- invoke: {
- src: async (context) => {
- // Transfer all xdai to the safe except INITIAL_ACCOUNT_XDAI
- const ownerAddress = RpcGateway.get().eth.accounts.privateKeyToAccount(context.data.privateKey).address;
- const totalAccountBalance = new BN(await RpcGateway.get().eth.getBalance(ownerAddress));
- const transferAmount = totalAccountBalance.sub(INITIAL_ACCOUNT_XDAI);
-
- const signedRawTransaction = await Web3Contract.signRawTransaction(
- ownerAddress,
- context.data.privateKey,
- context.data.profile.circlesAddress,
- "0x00",
- new BN(RpcGateway.get().utils.toWei("28000", "wei")),
- transferAmount);
-
- const execResult = await Web3Contract.sendSignedRawTransaction(signedRawTransaction);
- const receipt = await execResult.toPromise();
- localStorage.removeItem("fundsSafe");
- localStorage.setItem("signsUpAtCircles", "true");
- },
- onDone: "#hubSignup",
- onError: "#error"
- }
- },
- hubSignup: {
- id: "hubSignup",
- entry: () => {
- window.o.publishEvent({
- type: "shell.progress",
- message: `Finishing your setup (signing you up for UBI) ..`
- });
- },
- invoke: {
- src: async (context) => {
- const hub = new CirclesHub(RpcGateway.get(), HUB_ADDRESS);
- const hubSignupResult = await hub.signup(
- context.data.privateKey,
- new GnosisSafeProxy(RpcGateway.get(), context.data.profile.circlesAddress)
- );
- const receipt = await hubSignupResult.toPromise();
- localStorage.removeItem("signsUpAtCircles");
- localStorage.setItem("lastUBI", new Date().toJSON());
- console.log("Signed up at hub:", receipt);
- },
- onDone: "#success",
- onError: "#error"
- }
- },
- success: {
- id: 'success',
- type: 'final',
- entry: () => {
- push("#/banking/transactions");
- },
- data: (context, event: PlatformEvent) => {
- return context.data;
- }
- }
- },
-});
-
-export const deploySafe: ProcessDefinition = {
- name: "hubSignup",
- stateMachine: processDefinition,
-};
diff --git a/shell/src/dapps/o-banking/processes/getUBIService.ts b/shell/src/dapps/o-banking/processes/getUBIService.ts
deleted file mode 100644
index ee742ed2d..000000000
--- a/shell/src/dapps/o-banking/processes/getUBIService.ts
+++ /dev/null
@@ -1,18 +0,0 @@
-import {RpcGateway} from "@o-platform/o-circles/dist/rpcGateway";
-import {GnosisSafeProxy} from "@o-platform/o-circles/dist/safe/gnosisSafeProxy";
-import {CirclesAccount} from "@o-platform/o-circles/dist/model/circlesAccount";
-import {GetUbiContext} from "./getUbi";
-
-export const getUBIService = async (context:GetUbiContext) => {
- const ownerAddress = RpcGateway.get()
- .eth
- .accounts
- .privateKeyToAccount(context.data.privateKey)
- .address;
-
- const gnosisSafeProxy = new GnosisSafeProxy(RpcGateway.get(), context.data.safeAddress);
- const circlesAccount = new CirclesAccount(context.data.safeAddress);
- const result = await circlesAccount.getUBI(context.data.privateKey, gnosisSafeProxy);
-
- return result.toPromise();
-};
\ No newline at end of file
diff --git a/shell/src/dapps/o-banking/processes/getUbi.ts b/shell/src/dapps/o-banking/processes/getUbi.ts
deleted file mode 100644
index ff7eb68be..000000000
--- a/shell/src/dapps/o-banking/processes/getUbi.ts
+++ /dev/null
@@ -1,63 +0,0 @@
-import { ProcessDefinition } from "@o-platform/o-process/dist/interfaces/processManifest";
-import { ProcessContext } from "@o-platform/o-process/dist/interfaces/processContext";
-import { fatalError } from "@o-platform/o-process/dist/states/fatalError";
-import { createMachine } from "xstate";
-import {PlatformEvent} from "@o-platform/o-events/dist/platformEvent";
-import {RpcGateway} from "@o-platform/o-circles/dist/rpcGateway";
-import {GnosisSafeProxy} from "@o-platform/o-circles/dist/safe/gnosisSafeProxy";
-import {CirclesAccount} from "@o-platform/o-circles/dist/model/circlesAccount";
-import {emptySafe} from "../data/emptySafe";
-import {mySafe} from "../stores/safe";
-import {getUBIService} from "./getUBIService";
-
-export type GetUbiContextData = {
- safeAddress:string;
- privateKey:string;
-};
-
-/**
- * This is the context on which the process will work.
- * The actual fields are defined above in the 'AuthenticateContextData' type.
- * The 'AuthenticateContextData' type is also the return value of the process (see bottom for the signature).
- */
-export type GetUbiContext = ProcessContext;
-
-/**
- * In case you want to translate the flow later, it's nice to have the strings at one place.
- */
-const strings = {
-};
-
-const processDefinition = (processId: string) =>
-createMachine({
- id: `${processId}:getUbi`,
- initial: "getUbi",
- states: {
- // Include a default 'error' state that propagates the error by re-throwing it in an action.
- // TODO: Check if this works as intended
- ...fatalError("error"),
-
- // The code was either manually entered or pre-configured at launch.
- // Exchange it for the actual token and redirect the user to the application.
- getUbi: {
- id: "getUbi",
- invoke: {
- src: getUBIService,
- onDone: "#success",
- onError: "#error",
- },
- },
- success: {
- id: 'success',
- type: 'final',
- data: (context, event: PlatformEvent & {data:any}) => {
- return true;
- }
- }
- },
-});
-
-export const getUbi: ProcessDefinition = {
- name: "getUbi",
- stateMachine: processDefinition,
-};
diff --git a/shell/src/dapps/o-banking/processes/setTrust.ts b/shell/src/dapps/o-banking/processes/setTrust.ts
index d4227e5a0..ca274bc70 100644
--- a/shell/src/dapps/o-banking/processes/setTrust.ts
+++ b/shell/src/dapps/o-banking/processes/setTrust.ts
@@ -3,22 +3,33 @@ import { ProcessContext } from "@o-platform/o-process/dist/interfaces/processCon
import { fatalError } from "@o-platform/o-process/dist/states/fatalError";
import { createMachine } from "xstate";
import { prompt } from "@o-platform/o-process/dist/states/prompt";
-import TextEditor from "../../../../../packages/o-editors/src/TextEditor.svelte";
-import DropdownSelectEditor from "@o-platform/o-editors/src/DropdownSelectEditor.svelte";
import { PlatformEvent } from "@o-platform/o-events/dist/platformEvent";
-import gql from "graphql-tag";
-import { Choice } from "../../../../../packages/o-editors/src/choiceSelectorContext";
import { GnosisSafeProxy } from "@o-platform/o-circles/dist/safe/gnosisSafeProxy";
import { RpcGateway } from "@o-platform/o-circles/dist/rpcGateway";
import { CirclesHub } from "@o-platform/o-circles/dist/circles/circlesHub";
-import { HUB_ADDRESS } from "@o-platform/o-circles/dist/consts";
import { BN } from "ethereumjs-util";
+import { EditorViewContext } from "@o-platform/o-editors/src/shared/editorViewContext";
+import HtmlViewer from "@o-platform/o-editors/src/HtmlViewer.svelte";
+import TrustChangeConfirmation from "../molecules/TrustChangeConfirmation.svelte";
+import { promptCirclesSafe } from "../../../shared/api/promptCirclesSafe";
+import type { TransactionReceipt } from "web3-core";
+import { Environment } from "../../../shared/environment";
+
+import {
+ Profile,
+ ProfilesByCirclesAddressDocument,
+ ProfilesByCirclesAddressQueryVariables,
+} from "../../../shared/api/data/types";
+import { ApiClient } from "../../../shared/apiConnection";
export type SetTrustContextData = {
safeAddress: string;
+ hubAddress: string;
privateKey: string;
+ profile?: Profile;
trustReceiver?: string;
trustLimit?: number;
+ successAction?: (data: SetTrustContextData) => void;
};
/**
@@ -31,33 +42,47 @@ export type SetTrustContext = ProcessContext;
/**
* In case you want to translate the flow later, it's nice to have the strings at one place.
*/
-const strings = {
- labelTrustReceiver: "Enter the address of the account that you want to trust",
- labelTrustLimit: "Enter the trust limit (0-100)",
-};
-const trustUsersQuery = {
- query: gql`
- query safe($id: String!) {
- safe(id: $id) {
- incoming {
- userAddress
- canSendToAddress
- limit
- }
- outgoing {
- userAddress
- canSendToAddress
- limit
- }
- }
- }
- `,
- variables: {
- id: "0xd460db4cfa021c42edeb7e555d904400dab65ecc",
+const editorContent: { [x: string]: EditorViewContext } = {
+ recipient: {
+ title: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.recipient.title"),
+ description: "",
+ placeholder: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.recipient.placeholder"),
+ submitButtonText: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.recipient.submitButtonText"),
+ },
+ limit: {
+ title: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.limit.title"),
+ description: "",
+ submitButtonText: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.limit.submitButtonText"),
+ },
+ message: {
+ title: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.message.title"),
+ description: "",
+ submitButtonText: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.message.submitButtonText"),
+ },
+ confirm: {
+ title: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.confirm.title"),
+ description: "",
+ submitButtonText: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.confirm.submitButtonText"),
+ },
+ success: {
+ title: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.success.title"),
+ description: "",
+ submitButtonText: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.success.submitButtonText"),
},
};
+export async function fSetTrust(context: ProcessContext): Promise {
+ const gnosisSafeProxy = new GnosisSafeProxy(RpcGateway.get(), context.data.safeAddress);
+
+ return await new CirclesHub(RpcGateway.get(), Environment.circlesHubAddress).setTrust(
+ context.data.privateKey,
+ gnosisSafeProxy,
+ context.data.trustReceiver,
+ new BN(context.data.trustLimit.toString())
+ );
+}
+
const processDefinition = (processId: string) =>
createMachine({
id: `${processId}:setTrust`,
@@ -79,52 +104,20 @@ const processDefinition = (processId: string) =>
},
],
},
- trustReceiver: prompt({
- fieldName: "trustReceiver",
- component: DropdownSelectEditor,
+ trustReceiver: promptCirclesSafe({
+ field: "trustReceiver",
+ onlyWhenDirty: false,
params: {
- label: strings.labelTrustReceiver,
- graphql: true,
- asyncChoices: async (searchText?: string) => {
- const apiClient =
- await window.o.apiClient.client.subscribeToResult();
- const result = await apiClient.query({
- query: gql`
- query search($searchString: String!) {
- search(query: { searchString: $searchString }) {
- id
- circlesAddress
- firstName
- lastName
- dream
- country
- avatarUrl
- }
- }
- `,
- variables: {
- searchString: searchText ?? "",
- },
- });
-
- const items =
- result.data.search && result.data.search.length > 0
- ? result.data.search
- .map((o) => {
- return {
- value: o.circlesAddress,
- label: `${o.firstName} ${o.lastName}`,
- avatarUrl: o.avatarUrl,
- };
- })
- .filter((o) => o.value)
- : [];
-
- return items;
- },
- optionIdentifier: "value",
- getOptionLabel: (option) => option.label,
- getSelectionLabel: (option) => option.label,
+ view: (editorContent.recipient = {
+ title: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.recipient.title"),
+ description: "",
+ placeholder: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.recipient.placeholder"),
+ submitButtonText: window.o.i18n(
+ "dapps.o-banking.processes.setTrust.editorContent.recipient.submitButtonText"
+ ),
+ }),
+ placeholder: editorContent.recipient.placeholder,
+ submitButtonText: editorContent.recipient.submitButtonText,
},
navigation: {
next: "#checkTrustLimit",
@@ -134,27 +127,24 @@ const processDefinition = (processId: string) =>
id: "checkTrustLimit",
always: [
{
- cond: (context) =>
- context.data.trustLimit !== undefined &&
- context.data.trustLimit !== null,
+ cond: (context) => context.data.trustReceiver.toLowerCase() == context.data.safeAddress.toLowerCase(),
+ actions: (context) => {
+ context.messages["trustReceiver"] = window.o.i18n(
+ "dapps.o-banking.processes.setTrust.checkTrustLimit.contextMessage"
+ );
+ },
+ target: "#trustReceiver",
+ },
+ {
+ cond: (context) => context.data.trustLimit !== undefined && context.data.trustLimit !== null,
target: "#setTrust",
},
{
- target: "#trustLimit",
+ target: "#trustReceiver",
},
],
},
- trustLimit: prompt({
- fieldName: "trustLimit",
- component: TextEditor,
- params: {
- label: strings.labelTrustLimit,
- },
- navigation: {
- previous: "#checkTrustReceiver",
- next: "#setTrust",
- },
- }),
+
// The code was either manually entered or pre-configured at launch.
// Exchange it for the actual token and redirect the user to the application.
setTrust: {
@@ -162,42 +152,82 @@ const processDefinition = (processId: string) =>
entry: () => {
window.o.publishEvent({
type: "shell.progress",
- message: `Updating trust ..`,
+ message: window.o.i18n("dapps.o-banking.processes.setTrust.setTrust.message"),
});
},
invoke: {
src: async (context) => {
- const ownerAddress =
- RpcGateway.get().eth.accounts.privateKeyToAccount(
- context.data.privateKey
- ).address;
-
- const gnosisSafeProxy = new GnosisSafeProxy(
- RpcGateway.get(),
- context.data.safeAddress
- );
+ try {
+ const result = await ApiClient.query(
+ ProfilesByCirclesAddressDocument,
+ {
+ circlesAddresses: [context.data.trustReceiver],
+ }
+ );
+ context.data.profile = result;
+ } catch (error) {
+ console.info(`Could not load Profile for circlesAddress: ${context.data.trustReceiver}`);
+ }
- const execResult = await new CirclesHub(
- RpcGateway.get(),
- HUB_ADDRESS
- ).setTrust(
- context.data.privateKey,
- gnosisSafeProxy,
- context.data.trustReceiver,
- new BN(context.data.trustLimit.toString())
- );
+ return await fSetTrust(context);
+ },
+ onDone: "#showSuccess",
- return execResult.toPromise();
+ onError: {
+ target: "error",
+ actions: console.log,
},
- onDone: "#success",
- onError: "#error",
},
},
+
+ showSuccess: prompt({
+ id: "showSuccess",
+ field: "__",
+ component: TrustChangeConfirmation,
+ params: (context) => {
+ return {
+ view: (editorContent.success = {
+ title: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.success.title"),
+ description: "",
+ submitButtonText: window.o.i18n(
+ "dapps.o-banking.processes.setTrust.editorContent.success.submitButtonText"
+ ),
+ }),
+ profile: context.data.profile,
+ trustLimit: context.data.trustLimit,
+ submitButtonText: editorContent.success.submitButtonText,
+ hideNav: false,
+ };
+ },
+ navigation: {
+ next: "#success",
+ },
+ }),
+
+ error: prompt({
+ id: "error",
+ field: "__",
+ component: HtmlViewer,
+ params: {
+ view: (editorContent.message = {
+ title: window.o.i18n("dapps.o-banking.processes.setTrust.editorContent.message.title"),
+ description: "",
+ submitButtonText: window.o.i18n(
+ "dapps.o-banking.processes.setTrust.editorContent.message.submitButtonText"
+ ),
+ }),
+ html: () => "Oopsie, Something went wrong, please close this window and try again. ",
+ hideNav: false,
+ },
+ }),
success: {
type: "final",
id: "success",
data: (context, event: PlatformEvent) => {
- return "yeah!";
+ if (context.data.successAction) {
+ context.data.successAction(context.data);
+ }
+ return window.o.i18n("dapps.o-banking.proccesses.setTrust.success.return");
},
},
},
diff --git a/shell/src/dapps/o-banking/processes/showAssetDetail.ts b/shell/src/dapps/o-banking/processes/showAssetDetail.ts
new file mode 100644
index 000000000..560f6cc4a
--- /dev/null
+++ b/shell/src/dapps/o-banking/processes/showAssetDetail.ts
@@ -0,0 +1,54 @@
+import { ProcessDefinition } from "@o-platform/o-process/dist/interfaces/processManifest";
+import { ProcessContext } from "@o-platform/o-process/dist/interfaces/processContext";
+import { fatalError } from "@o-platform/o-process/dist/states/fatalError";
+import { createMachine } from "xstate";
+import { PlatformEvent } from "@o-platform/o-events/dist/platformEvent";
+import {show} from "@o-platform/o-process/dist/actions/show";
+import AssetDetail from "../pages/AssetDetail.svelte";
+
+export type ShowAssetDetailContextData = {
+ id: string;
+};
+
+export type ShowAssetDetailContext = ProcessContext;
+
+const processDefinition = (processId: string) =>
+ createMachine({
+ id: `${processId}:showAssetDetail`,
+ initial: "showAssetDetail",
+ states: {
+ // Include a default 'error' state that propagates the error by re-throwing it in an action.
+ // TODO: Check if this works as intended
+ ...fatalError("error"),
+
+ showAssetDetail: {
+ id: "showAssetDetail",
+ entry: show({
+ field: "__",
+ component: AssetDetail,
+ params: (context) => {
+ return {
+ id: context.data.id
+ }
+ },
+ navigation: {
+ canGoBack: () => false,
+ canSkip: () => false,
+ next: "#success"
+ }
+ })
+ },
+ success: {
+ type: "final",
+ id: "success",
+ data: (context, event: PlatformEvent) => {
+ return window.o.i18n("dapps.o-banking.processes.showAssetDetail.success.return");
+ },
+ },
+ },
+ });
+
+export const showAssetDetail: ProcessDefinition = {
+ name: "showAssetDetail",
+ stateMachine: processDefinition,
+};
diff --git a/shell/src/dapps/o-banking/processes/showProfile.ts b/shell/src/dapps/o-banking/processes/showProfile.ts
new file mode 100644
index 000000000..b7e972e6d
--- /dev/null
+++ b/shell/src/dapps/o-banking/processes/showProfile.ts
@@ -0,0 +1,54 @@
+import { ProcessDefinition } from "@o-platform/o-process/dist/interfaces/processManifest";
+import { ProcessContext } from "@o-platform/o-process/dist/interfaces/processContext";
+import { fatalError } from "@o-platform/o-process/dist/states/fatalError";
+import { createMachine } from "xstate";
+import { PlatformEvent } from "@o-platform/o-events/dist/platformEvent";
+import {show} from "@o-platform/o-process/dist/actions/show";
+import Profile from "../molecules/Profile.svelte";
+
+export type ShowProfileContextData = {
+ id: string;
+};
+
+export type ShowProfileContext = ProcessContext;
+
+const processDefinition = (processId: string) =>
+ createMachine({
+ id: `${processId}:showProfile`,
+ initial: "showProfile",
+ states: {
+ // Include a default 'error' state that propagates the error by re-throwing it in an action.
+ // TODO: Check if this works as intended
+ ...fatalError("error"),
+
+ showProfile: {
+ id: "showProfile",
+ entry: show({
+ field: "__",
+ component: Profile,
+ params: (context) => {
+ return {
+ id: context.data.id
+ }
+ },
+ navigation: {
+ canGoBack: () => false,
+ canSkip: () => false,
+ next: "#success"
+ }
+ })
+ },
+ success: {
+ type: "final",
+ id: "success",
+ data: (context, event: PlatformEvent) => {
+ return window.o.i18n("dapps.o-banking.processes.showProfile.success.return");
+ },
+ },
+ },
+ });
+
+export const showProfile: ProcessDefinition = {
+ name: "showProfile",
+ stateMachine: processDefinition,
+};
diff --git a/shell/src/dapps/o-banking/processes/showTransaction.ts b/shell/src/dapps/o-banking/processes/showTransaction.ts
new file mode 100644
index 000000000..5b01ae605
--- /dev/null
+++ b/shell/src/dapps/o-banking/processes/showTransaction.ts
@@ -0,0 +1,54 @@
+import { ProcessDefinition } from "@o-platform/o-process/dist/interfaces/processManifest";
+import { ProcessContext } from "@o-platform/o-process/dist/interfaces/processContext";
+import { fatalError } from "@o-platform/o-process/dist/states/fatalError";
+import { createMachine } from "xstate";
+import { PlatformEvent } from "@o-platform/o-events/dist/platformEvent";
+import {show} from "@o-platform/o-process/dist/actions/show";
+import TransactionDetail from "../pages/TransactionDetail.svelte";
+
+export type ShowTransactionContextData = {
+ id: string;
+};
+
+export type ShowTransactionContext = ProcessContext;
+
+const processDefinition = (processId: string) =>
+ createMachine({
+ id: `${processId}:showTransaction`,
+ initial: "showTransaction",
+ states: {
+ // Include a default 'error' state that propagates the error by re-throwing it in an action.
+ // TODO: Check if this works as intended
+ ...fatalError("error"),
+
+ showTransaction: {
+ id: "showTransaction",
+ entry: show({
+ field: "__",
+ component: TransactionDetail,
+ params: (context) => {
+ return {
+ id: context.data.id
+ }
+ },
+ navigation: {
+ canGoBack: () => false,
+ canSkip: () => false,
+ next: "#success"
+ }
+ })
+ },
+ success: {
+ type: "final",
+ id: "success",
+ data: (context, event: PlatformEvent) => {
+ return window.o.i18n("dapps.o-banking.processes.showTransaction.success.return");
+ },
+ },
+ },
+ });
+
+export const showTransaction: ProcessDefinition = {
+ name: "showTransaction",
+ stateMachine: