diff --git a/amplify/backend/api/colonycdapp/schema/schema.graphql b/amplify/backend/api/colonycdapp/schema/schema.graphql
index 88eed65702..97e339c3c3 100644
--- a/amplify/backend/api/colonycdapp/schema/schema.graphql
+++ b/amplify/backend/api/colonycdapp/schema/schema.graphql
@@ -893,6 +893,34 @@ enum ColonyActionType {
"""
FINALIZE_EXPENDITURE_MOTION
"""
+ An action related to creating a streaming payment
+ """
+ CREATE_STREAMING_PAYMENT
+ """
+ An action related to creating a streaming payment via a motion
+ """
+ CREATE_STREAMING_PAYMENT_MOTION
+ """
+ An action related to cancelling a streaming payment
+ """
+ CANCEL_STREAMING_PAYMENT
+ """
+ An action related to cancelling and waiving a streaming payment
+ """
+ CANCEL_AND_WAIVE_STREAMING_PAYMENT
+ """
+ An action related to cancelling a streaming payment via a motion
+ """
+ CANCEL_STREAMING_PAYMENT_MOTION
+ """
+ An action related to editing a streaming payment
+ """
+ EDIT_STREAMING_PAYMENT
+ """
+ An action related to editing a streaming payment via a motion
+ """
+ EDIT_STREAMING_PAYMENT_MOTION
+ """
An action related to adding / removing approved colony tokens
"""
MANAGE_TOKENS
@@ -1627,8 +1655,16 @@ type Colony @model {
"""
reputation: String
+ """
+ Expenditures within the colony
+ """
expenditures: [Expenditure] @hasMany(indexName: "byColony", fields: ["id"])
"""
+ Streaming payments within the colony
+ """
+ streamingPayments: [StreamingPayment]
+ @hasMany(indexName: "byColony", fields: ["id"])
+ """
Global claim delay for expenditures (in seconds)
"""
expendituresGlobalClaimDelay: String
@@ -3010,6 +3046,40 @@ type ColonyMotion @model {
the details of tokens and amounts to be funded
"""
expenditureFunding: [ExpenditureFundingItem!]
+
+ """
+ ID of the associated streaming payment, if any
+ """
+ streamingPaymentId: ID
+ @index(
+ name: "byStreamingPaymentId"
+ queryField: "getMotionByStreamingPaymentId"
+ )
+
+ """
+ Streaming payment associated with the action, if any
+ """
+ streamingPayment: StreamingPayment @hasOne(fields: ["streamingPaymentId"])
+
+ """
+ Pending streaming payment to be created by motion, if any
+ """
+ pendingStreamingPayment: PendingStreamingPayment
+
+ """
+ Streaming Payment changes by the action
+ """
+ pendingStreamingPaymentChanges: StreamingPaymentChanges
+
+ """
+ Identifier of streaming payment metadata that is stored temporarily and committed to the database once the corresponding motion passes
+ """
+ pendingStreamingPaymentMetadataId: ID
+ """
+ Streaming payment metadata that is stored temporarily and committed to the database once the corresponding motion passes
+ """
+ pendingStreamingPaymentMetadata: StreamingPaymentMetadata
+ @hasOne(fields: ["pendingStreamingPaymentMetadataId"])
}
type ExpenditureFundingItem {
@@ -3525,6 +3595,41 @@ type ColonyAction @model @searchable {
expenditureSlotIds: [Int!]
arbitraryTransactions: [ColonyActionArbitraryTransaction!]
+ """
+ ID of the associated streaming payment, if any
+ """
+ streamingPaymentId: ID
+ @index(
+ name: "byStreamingPaymentId"
+ queryField: "getActionByStreamingPaymentId"
+ )
+ """
+ Streaming payment associated with the action, if any
+ """
+ streamingPayment: StreamingPayment @hasOne(fields: ["streamingPaymentId"])
+ """
+ Changes to the streaming payment associated with the action, if any
+ Applicable to `EDIT_STREAMING_PAYMENT` action only
+ """
+ streamingPaymentChanges: StreamingPaymentChangeSet
+}
+
+type StreamingPaymentChangeSet {
+ """
+ The values before the change
+ """
+ oldValues: StreamingPaymentChanges!
+ """
+ The values before the change
+ """
+ newValues: StreamingPaymentChanges!
+}
+
+type StreamingPaymentChanges {
+ startTime: String!
+ endTime: String!
+ interval: String!
+ amount: String!
}
"""
@@ -3978,23 +4083,121 @@ type ExpenditureStage {
name: String!
}
-type StreamingPayment @model {
+type StreamingPayment @model @searchable {
id: ID! # Self-managed, formatted as colonyId_nativeId
+ """
+ Native ID of the streaming payment within a colony
+ """
nativeId: Int!
+ """
+ Colony ID (address) to which the expenditure belongs
+ """
+ colonyId: ID!
+ @index(
+ name: "byColony"
+ queryField: "getStreamingPaymentsByColony"
+ sortKeyFields: ["createdAt"]
+ )
+ """
+ The Colony to which the expenditure belongs
+ """
+ colony: Colony! @belongsTo(fields: ["colonyId"])
createdAt: AWSDateTime!
recipientAddress: String!
nativeDomainId: Int!
- startTime: AWSTimestamp!
- endTime: AWSTimestamp!
+ startTime: String!
+ endTime: String!
interval: String!
- payouts: [ExpenditurePayout!]
+ tokenAddress: ID!
+ token: Token @hasOne(fields: ["tokenAddress"])
+ amount: String!
+ claims: [StreamingPaymentClaim!]
metadata: StreamingPaymentMetadata @hasOne(fields: ["id"])
+ """
+ Actions associated with the streaming payment
+ """
+ actions: [ColonyAction!]
+ @hasMany(indexName: "byStreamingPaymentId", fields: ["id"])
+ """
+ Is the stream cancelled?
+ """
+ isCancelled: Boolean
+ """
+ Is the stream waived?
+ """
+ isWaived: Boolean
+ """
+ The motions created that relate to this streaming payment, if there are any
+ """
+ motions: [ColonyMotion]
+ @hasMany(indexName: "byStreamingPaymentId", fields: ["id"])
+ """
+ Address of the stream creator, can be a user or an extension
+ """
+ creatorAddress: ID!
+}
+
+type PendingStreamingPayment {
+ """
+ Address of the recipient
+ """
+ recipientAddress: String!
+ """
+ Native domain ID where the streaming payment will be created
+ """
+ nativeDomainId: Int!
+ """
+ Start time in seconds since epoch
+ """
+ startTime: String!
+ """
+ End time in seconds since epoch
+ """
+ endTime: String!
+ """
+ Payment interval in seconds
+ """
+ interval: String!
+ """
+ Token address used for payments
+ """
+ tokenAddress: ID!
+ """
+ Amount per interval
+ """
+ amount: String!
}
type StreamingPaymentMetadata @model {
id: ID! # Self-managed, formatted as colonyId_nativeId
endCondition: StreamingPaymentEndCondition!
- limitAmount: String
+ """
+ List of Streaming Payment metadata changelog entries
+ """
+ changelog: [StreamingPaymentMetadataChangelog!]
+}
+
+"""
+Represents a changelog entry for Streaming Payment metadata
+"""
+type StreamingPaymentMetadataChangelog {
+ """
+ Transaction hash associated with the changelog entry
+ """
+ transactionHash: String!
+ """
+ The end condition before the change
+ """
+ oldEndCondition: StreamingPaymentEndCondition!
+ """
+ The end condition after the change
+ """
+ newEndCondition: StreamingPaymentEndCondition!
+}
+
+type StreamingPaymentClaim {
+ amount: String!
+ timestamp: String!
}
"""
diff --git a/amplify/backend/backend-config.json b/amplify/backend/backend-config.json
index b03ccb9bcd..1cae8639c1 100644
--- a/amplify/backend/backend-config.json
+++ b/amplify/backend/backend-config.json
@@ -281,5 +281,263 @@
"providerPlugin": "awscloudformation",
"service": "Lambda"
}
+ },
+ "parameters": {
+ "AMPLIFY_function_colonycdappSSMAccess_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "colonycdappSSMAccess"
+ }
+ ]
+ },
+ "AMPLIFY_function_colonycdappSSMAccess_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "colonycdappSSMAccess"
+ }
+ ]
+ },
+ "AMPLIFY_function_createColonyEtherealMetadata_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "createColonyEtherealMetadata"
+ }
+ ]
+ },
+ "AMPLIFY_function_createColonyEtherealMetadata_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "createColonyEtherealMetadata"
+ }
+ ]
+ },
+ "AMPLIFY_function_createPrivateBetaInvite_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "createPrivateBetaInvite"
+ }
+ ]
+ },
+ "AMPLIFY_function_createPrivateBetaInvite_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "createPrivateBetaInvite"
+ }
+ ]
+ },
+ "AMPLIFY_function_createUniqueUser_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "createUniqueUser"
+ }
+ ]
+ },
+ "AMPLIFY_function_createUniqueUser_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "createUniqueUser"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchColonyBalances_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchColonyBalances"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchColonyBalances_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchColonyBalances"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchColonyNativeFundsClaim_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchColonyNativeFundsClaim"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchColonyNativeFundsClaim_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchColonyNativeFundsClaim"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchMotionState_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchMotionState"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchMotionState_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchMotionState"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchMotionTimeoutPeriods_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchMotionTimeoutPeriods"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchMotionTimeoutPeriods_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchMotionTimeoutPeriods"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchTokenFromChain_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchTokenFromChain"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchTokenFromChain_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchTokenFromChain"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchVoterRewards_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchVoterRewards"
+ }
+ ]
+ },
+ "AMPLIFY_function_fetchVoterRewards_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "fetchVoterRewards"
+ }
+ ]
+ },
+ "AMPLIFY_function_getSafeTransactionStatus_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "getSafeTransactionStatus"
+ }
+ ]
+ },
+ "AMPLIFY_function_getSafeTransactionStatus_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "getSafeTransactionStatus"
+ }
+ ]
+ },
+ "AMPLIFY_function_getUserReputation_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "getUserReputation"
+ }
+ ]
+ },
+ "AMPLIFY_function_getUserReputation_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "getUserReputation"
+ }
+ ]
+ },
+ "AMPLIFY_function_getUserTokenBalance_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "getUserTokenBalance"
+ }
+ ]
+ },
+ "AMPLIFY_function_getUserTokenBalance_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "getUserTokenBalance"
+ }
+ ]
+ },
+ "AMPLIFY_function_qaSSMtest_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "qaSSMtest"
+ }
+ ]
+ },
+ "AMPLIFY_function_qaSSMtest_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "qaSSMtest"
+ }
+ ]
+ },
+ "AMPLIFY_function_updateContributorsWithReputation_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "updateContributorsWithReputation"
+ }
+ ]
+ },
+ "AMPLIFY_function_updateContributorsWithReputation_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "updateContributorsWithReputation"
+ }
+ ]
+ },
+ "AMPLIFY_function_validateUserInvite_deploymentBucketName": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "validateUserInvite"
+ }
+ ]
+ },
+ "AMPLIFY_function_validateUserInvite_s3Key": {
+ "usedBy": [
+ {
+ "category": "function",
+ "resourceName": "validateUserInvite"
+ }
+ ]
+ }
}
}
\ No newline at end of file
diff --git a/docker/colony-cdapp-dev-env-block-ingestor b/docker/colony-cdapp-dev-env-block-ingestor
index 4e247afd99..308289a280 100644
--- a/docker/colony-cdapp-dev-env-block-ingestor
+++ b/docker/colony-cdapp-dev-env-block-ingestor
@@ -1,6 +1,6 @@
FROM colony-cdapp-dev-env/base:latest
-ENV BLOCK_INGESTOR_HASH=de36c3611e9d40c1bdf4f906af18ce34fab61eab
+ENV BLOCK_INGESTOR_HASH=97bca4c0a96a0d78b5a78961dfcc48a7009909ff
# Declare volumes to set up metadata
VOLUME [ "/colonyCDapp/amplify/mock-data" ]
diff --git a/package-lock.json b/package-lock.json
index b4d6a3b87d..a52f81ee55 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -6997,6 +6997,7 @@
"resolved": "https://registry.npmjs.org/@limegrass/eslint-plugin-import-alias/-/eslint-plugin-import-alias-1.4.1.tgz",
"integrity": "sha512-3aWSwwih7CRfZu6XnoduuHn3PeeuhkYag+cDSNJG37xH2/zOp84DOhyJaBXNxU/NyNbB3XjF4o7P37EN1yep/g==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"fs-extra": "^10.0.1",
"micromatch": "^4.0.0",
@@ -7012,6 +7013,7 @@
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"graceful-fs": "^4.2.0",
"jsonfile": "^6.0.1",
@@ -7026,6 +7028,7 @@
"resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz",
"integrity": "sha512-vavAMRXOgBVNF6nyEEmL3DBK19iRpDcoIwW+swQ+CbGiu7lju6t+JklA1MHweoWtadgt4ISVUsXLyDq34ddcwA==",
"dev": true,
+ "license": "MIT",
"engines": {
"node": ">=4"
}
@@ -7035,6 +7038,7 @@
"resolved": "https://registry.npmjs.org/tsconfig-paths/-/tsconfig-paths-4.2.0.tgz",
"integrity": "sha512-NoZ4roiN7LnbKn9QqE1amc9DJfzvZXxF4xDavcOWt1BPkdx+m+0gJuPM+S0vCe7zTJMYUP0R8pO2XMr+Y8oLIg==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"json5": "^2.2.2",
"minimist": "^1.2.6",
@@ -22877,6 +22881,7 @@
"resolved": "https://registry.npmjs.org/eslint/-/eslint-8.57.0.tgz",
"integrity": "sha512-dZ6+mexnaTIbSBZWgou51U6OmzIhYM2VcNdtiTtI7qPNZm35Akpr0f6vtw3w1Kmn5PYo+tZVfh13WrhpS6oLqQ==",
"dev": true,
+ "license": "MIT",
"dependencies": {
"@eslint-community/eslint-utils": "^4.2.0",
"@eslint-community/regexpp": "^4.6.1",
diff --git a/src/components/v5/common/CompletedAction/CompletedAction.tsx b/src/components/v5/common/CompletedAction/CompletedAction.tsx
index 8dfcd100c1..586c7f2296 100644
--- a/src/components/v5/common/CompletedAction/CompletedAction.tsx
+++ b/src/components/v5/common/CompletedAction/CompletedAction.tsx
@@ -149,10 +149,12 @@ const CompletedAction = ({ action }: ICompletedAction) => {
case ColonyActionType.ReleaseStagedPaymentsMotion:
case ColonyActionType.MakeArbitraryTransactionsMotion:
case ColonyActionType.EditExpenditureMotion:
- case ColonyActionType.FundExpenditureMotion: {
+ case ColonyActionType.FundExpenditureMotion:
+ case ColonyActionType.CancelStreamingPaymentMotion:
+ case ColonyActionType.EditStreamingPaymentMotion:
+ case ColonyActionType.CreateStreamingPaymentMotion: {
const { motionData } = action;
- // @NOTE: Enabling expenditure-related motions above temporarily (action UI will be missing)
return motionData ? (
) : null;
diff --git a/src/components/v5/frame/ColonyHome/ColonyHome.tsx b/src/components/v5/frame/ColonyHome/ColonyHome.tsx
index ae282b8623..b936c2ef8a 100644
--- a/src/components/v5/frame/ColonyHome/ColonyHome.tsx
+++ b/src/components/v5/frame/ColonyHome/ColonyHome.tsx
@@ -12,6 +12,7 @@ import { formatText } from '~utils/intl.ts';
import useGetActionFormData from '~v5/common/ActionSidebar/hooks/useGetActionFormData.ts';
import Link from '~v5/shared/Link/index.ts';
import TeamFilter from '~v5/shared/TeamFilter/TeamFilter.tsx';
+import TmpStreamingPayments from '~v5/tmpDebug/TmpStreamingPayments.tsx';
import DashboardHeader from './partials/DashboardHeader/index.ts';
import FundsCards from './partials/FundsCards/index.ts';
@@ -32,6 +33,8 @@ const ColonyHome = () => {
className="flex flex-grow flex-col gap-6 sm:min-h-full md:gap-4.5"
data-tour={TourTargets.Dashboard}
>
+ {/* @TODO: Remove before merging to master */}
+
diff --git a/src/components/v5/tmpDebug/TmpStreamingPayments.tsx b/src/components/v5/tmpDebug/TmpStreamingPayments.tsx
new file mode 100644
index 0000000000..8add532434
--- /dev/null
+++ b/src/components/v5/tmpDebug/TmpStreamingPayments.tsx
@@ -0,0 +1,759 @@
+import { gql, useLazyQuery } from '@apollo/client';
+import { Id } from '@colony/colony-js';
+import { BigNumber } from 'ethers';
+import moveDecimal from 'move-decimal-point';
+import React, { useState } from 'react';
+
+import { DEFAULT_TOKEN_DECIMALS } from '~constants';
+import { useAppContext } from '~context/AppContext/AppContext.ts';
+import { useColonyContext } from '~context/ColonyContext/ColonyContext.ts';
+import {
+ StreamingPaymentEndCondition,
+ useGetStreamingPaymentQuery,
+} from '~gql';
+import useAsyncFunction from '~hooks/useAsyncFunction.ts';
+import useCurrentBlockTime from '~hooks/useCurrentBlockTime.ts';
+import useEnabledExtensions from '~hooks/useEnabledExtensions.ts';
+import useStreamingPaymentAmountsLeft from '~hooks/useStreamingPaymentAmountsLeft.ts';
+import { ActionTypes } from '~redux';
+import { type ClaimStreamingPaymentPayload } from '~redux/sagas/expenditures/claimStreamingPayment.ts';
+import { type CreateStreamingPaymentPayload } from '~redux/sagas/expenditures/createStreamingPayment.ts';
+import {
+ type EditStreamingPaymentPayload,
+ type CancelStreamingPaymentPayload,
+} from '~redux/types/actions/expenditures.ts';
+import {
+ type StreamingPaymentsMotionEditPayload,
+ type StreamingPaymentsMotionCancelPayload,
+ type StreamingPaymentsMotionCreatePayload,
+} from '~redux/types/actions/motion.ts';
+import Numeral from '~shared/Numeral/Numeral.tsx';
+import { getStreamingPaymentDatabaseId } from '~utils/databaseId.ts';
+import { findDomainByNativeId } from '~utils/domains.ts';
+import { getStreamingPaymentLimit } from '~utils/streamingPayments.ts';
+import { getSelectedToken } from '~utils/tokens.ts';
+import InputBase from '~v5/common/Fields/InputBase/InputBase.tsx';
+import Select from '~v5/common/Fields/Select/Select.tsx';
+import Switch from '~v5/common/Fields/Switch/Switch.tsx';
+import Button from '~v5/shared/Button/Button.tsx';
+import { ActionButton } from '~v5/shared/Button/index.ts';
+
+import { useTmpContext } from './context/TmpContext.ts';
+
+enum StartTime {
+ Now = 'now',
+ OneWeekAgo = 'one-week-ago',
+ OneWeekFromNow = 'one-week-from-now',
+ TwoWeeksFromNow = 'two-weeks-from-now',
+}
+
+enum EndTime {
+ TwoWeeksFromNow = 'two-weeks-from-now',
+ ThreeWeeksFromNow = 'three-weeks-from-now',
+ FourWeeksFromNow = 'four-weeks-from-now',
+}
+
+enum Interval {
+ Hourly = 'hourly',
+ Daily = 'daily',
+ Weekly = 'weekly',
+}
+
+const TmpStreamingPayments = () => {
+ const { colony } = useColonyContext();
+ const { user } = useAppContext();
+ const { streamingPaymentsAddress, votingReputationAddress } =
+ useEnabledExtensions();
+ const [getStreamingPayments] = useLazyQuery(gql`
+ query ListStreamingPayments {
+ listStreamingPayments {
+ nextToken
+ items {
+ nativeId
+ }
+ }
+ }
+ `);
+ const { annotation } = useTmpContext();
+
+ const { currentBlockTime: blockTime, fetchCurrentBlockTime } =
+ useCurrentBlockTime();
+
+ const [tokenAddress, setTokenAddress] = useState(
+ colony.nativeToken.tokenAddress,
+ );
+ const [decimalAmount, setDecimalAmount] = useState('18');
+ const [transactionAmount, setTransactionAmount] = useState('0');
+ const [endCondition, setEndCondition] = useState(
+ StreamingPaymentEndCondition.FixedTime,
+ );
+ const [selectedStartTime, setSelectedStartTime] = useState(StartTime.Now);
+ const [selectedEndTime, setSelectedEndTime] = useState(
+ EndTime.TwoWeeksFromNow,
+ );
+ const [selectedInterval, setSelectedInterval] = useState(Interval.Hourly);
+ const [limit, setLimit] = useState('0');
+ const [streamingPaymentId, setStreamingPaymentId] = useState('');
+ const [updateStartTime, setUpdateStartTime] = useState(false);
+ const [updateEndTime, setUpdateEndTime] = useState(false);
+ const [updateAmount, setUpdateAmount] = useState(false);
+ const [updateInterval, setUpdateInterval] = useState(false);
+ const [updateEndCondition, setUpdateEndCondition] = useState(false);
+ const [updateLimit, setUpdateLimit] = useState(false);
+
+ const { data, refetch } = useGetStreamingPaymentQuery({
+ variables: {
+ streamingPaymentId: getStreamingPaymentDatabaseId(
+ colony.colonyAddress,
+ Number(streamingPaymentId),
+ ),
+ },
+ skip: Number.isNaN(streamingPaymentId),
+ fetchPolicy: 'network-only',
+ });
+ const streamingPayment = data?.getStreamingPayment;
+
+ const cancel = useAsyncFunction({
+ submit: ActionTypes.STREAMING_PAYMENT_CANCEL,
+ error: ActionTypes.STREAMING_PAYMENT_CANCEL_ERROR,
+ success: ActionTypes.STREAMING_PAYMENT_CANCEL_SUCCESS,
+ });
+ const claim = useAsyncFunction({
+ submit: ActionTypes.STREAMING_PAYMENT_CLAIM,
+ error: ActionTypes.STREAMING_PAYMENT_CLAIM_ERROR,
+ success: ActionTypes.STREAMING_PAYMENT_CLAIM_SUCCESS,
+ });
+ const editStreamingPayment = useAsyncFunction({
+ submit: ActionTypes.STREAMING_PAYMENT_EDIT,
+ error: ActionTypes.STREAMING_PAYMENT_EDIT_ERROR,
+ success: ActionTypes.STREAMING_PAYMENT_EDIT_SUCCESS,
+ });
+ const editStreamingPaymentMotion = useAsyncFunction({
+ submit: ActionTypes.MOTION_STREAMING_PAYMENT_EDIT,
+ error: ActionTypes.MOTION_STREAMING_PAYMENT_EDIT_ERROR,
+ success: ActionTypes.MOTION_STREAMING_PAYMENT_EDIT_SUCCESS,
+ });
+ const cancelMotion = useAsyncFunction({
+ submit: ActionTypes.MOTION_STREAMING_PAYMENT_CANCEL,
+ error: ActionTypes.MOTION_STREAMING_PAYMENT_CANCEL_ERROR,
+ success: ActionTypes.MOTION_STREAMING_PAYMENT_CANCEL_SUCCESS,
+ });
+
+ const { amountAvailableToClaim, amountClaimedToDate } =
+ useStreamingPaymentAmountsLeft(
+ streamingPayment,
+ Math.floor(blockTime ?? Date.now() / 1000),
+ );
+
+ const rootDomain = findDomainByNativeId(Id.RootDomain, colony);
+ if (!rootDomain) {
+ return null;
+ }
+
+ const getStartTime = (startTime: StartTime) => {
+ switch (startTime) {
+ case StartTime.OneWeekAgo: {
+ return BigNumber.from(
+ (blockTime ?? Math.floor(Date.now() / 1000)) - 604800,
+ ).toString();
+ }
+ case StartTime.OneWeekFromNow: {
+ return BigNumber.from(
+ (blockTime ?? Math.floor(Date.now() / 1000)) + 604800,
+ ).toString();
+ }
+ case StartTime.TwoWeeksFromNow: {
+ return BigNumber.from(
+ (blockTime ?? Math.floor(Date.now() / 1000)) + 604800 * 2,
+ ).toString();
+ }
+ case StartTime.Now:
+ default: {
+ return BigNumber.from(
+ blockTime ?? Math.floor(Date.now() / 1000),
+ ).toString();
+ }
+ }
+ };
+
+ const getEndTime = (endTime: EndTime) => {
+ switch (endTime) {
+ case EndTime.FourWeeksFromNow: {
+ return BigNumber.from(
+ (blockTime ?? Math.floor(Date.now() / 1000)) + 604800 * 4,
+ ).toString();
+ }
+ case EndTime.ThreeWeeksFromNow: {
+ return BigNumber.from(
+ (blockTime ?? Math.floor(Date.now() / 1000)) + 604800 * 3,
+ ).toString();
+ }
+ case EndTime.TwoWeeksFromNow:
+ default: {
+ return BigNumber.from(
+ (blockTime ?? Math.floor(Date.now() / 1000)) + 604800 * 2,
+ ).toString();
+ }
+ }
+ };
+
+ const getInterval = (interval: Interval) => {
+ switch (interval) {
+ case Interval.Weekly: {
+ return 3600 * 24 * 7;
+ }
+ case Interval.Daily: {
+ return 3600 * 24;
+ }
+ case Interval.Hourly:
+ default: {
+ return 3600;
+ }
+ }
+ };
+
+ const createStreamingPaymentPayload: CreateStreamingPaymentPayload = {
+ colonyAddress: colony.colonyAddress,
+ createdInDomain: rootDomain,
+ amount: transactionAmount,
+ endCondition,
+ interval: getInterval(selectedInterval),
+ recipientAddress: user?.walletAddress ?? '',
+ startTimestamp: getStartTime(selectedStartTime),
+ tokenAddress,
+ tokenDecimals: parseInt(decimalAmount, 10),
+ endTimestamp: getEndTime(selectedEndTime),
+ limitAmount: limit,
+ annotationMessage: annotation,
+ };
+
+ const handleCancel = async ({
+ shouldWaive,
+ }: Pick
) => {
+ if (!streamingPayment) {
+ return;
+ }
+
+ const payload: CancelStreamingPaymentPayload = {
+ colonyAddress: colony.colonyAddress,
+ streamingPayment,
+ userAddress: user?.walletAddress ?? '',
+ shouldWaive,
+ annotationMessage: annotation,
+ };
+
+ await cancel(payload);
+ };
+
+ const handleClaim = async () => {
+ if (!streamingPayment) {
+ return;
+ }
+
+ const claimPayload: ClaimStreamingPaymentPayload = {
+ colonyAddress: colony.colonyAddress,
+ streamingPaymentsAddress: streamingPaymentsAddress ?? '',
+ streamingPayment,
+ };
+
+ await claim(claimPayload);
+ };
+
+ const handleCancelMotion = async () => {
+ if (!streamingPayment || !votingReputationAddress) {
+ return;
+ }
+
+ const payload: StreamingPaymentsMotionCancelPayload = {
+ colony,
+ motionDomainId: Id.RootDomain,
+ streamingPayment,
+ votingReputationAddress,
+ annotationMessage: annotation,
+ };
+
+ await cancelMotion(payload);
+ };
+
+ const handleGetLatestMotionId = () => {
+ getStreamingPayments({
+ onCompleted: (d) => {
+ if (d) {
+ const latestStreamingPaymentNativeID =
+ d?.listStreamingPayments?.items?.length;
+
+ if (!latestStreamingPaymentNativeID) return;
+
+ setStreamingPaymentId(latestStreamingPaymentNativeID || '');
+ }
+ },
+ });
+ };
+
+ const handleEdit = async () => {
+ if (!streamingPayment || !streamingPaymentsAddress) {
+ return;
+ }
+
+ const fixedPayload: EditStreamingPaymentPayload = {
+ colony,
+ streamingPayment,
+ streamingPaymentsAddress,
+ startTimestamp: updateStartTime
+ ? getStartTime(selectedStartTime)
+ : undefined,
+ amount: updateAmount ? transactionAmount : undefined,
+ interval: updateInterval ? getInterval(selectedInterval) : undefined,
+ endCondition: StreamingPaymentEndCondition.FixedTime,
+ endTimestamp: updateEndTime ? getEndTime(selectedEndTime) : undefined,
+ };
+
+ const limitPayload: EditStreamingPaymentPayload = {
+ colony,
+ streamingPayment,
+ streamingPaymentsAddress,
+ startTimestamp: updateStartTime
+ ? getStartTime(selectedStartTime)
+ : undefined,
+ amount: updateAmount ? transactionAmount : undefined,
+ interval: updateInterval ? getInterval(selectedInterval) : undefined,
+ endCondition: StreamingPaymentEndCondition.LimitReached,
+ limitAmount: updateLimit ? limit : undefined,
+ };
+
+ const whenCancelledPayload: EditStreamingPaymentPayload = {
+ colony,
+ streamingPayment,
+ streamingPaymentsAddress,
+ startTimestamp: updateStartTime
+ ? getStartTime(selectedStartTime)
+ : undefined,
+ amount: updateAmount ? transactionAmount : undefined,
+ interval: updateInterval ? getInterval(selectedInterval) : undefined,
+ endCondition: StreamingPaymentEndCondition.WhenCancelled,
+ };
+
+ const undefinedEndConditionPayload: EditStreamingPaymentPayload = {
+ colony,
+ streamingPayment,
+ streamingPaymentsAddress,
+ startTimestamp: updateStartTime
+ ? getStartTime(selectedStartTime)
+ : undefined,
+ endTimestamp: updateEndTime ? getEndTime(selectedEndTime) : undefined,
+ amount: updateAmount ? transactionAmount : undefined,
+ interval: updateInterval ? getInterval(selectedInterval) : undefined,
+ limitAmount: updateLimit ? limit : undefined,
+ };
+
+ let payload: EditStreamingPaymentPayload = undefinedEndConditionPayload;
+
+ if (updateEndCondition) {
+ if (endCondition === StreamingPaymentEndCondition.FixedTime) {
+ payload = fixedPayload;
+ }
+ if (endCondition === StreamingPaymentEndCondition.LimitReached) {
+ payload = limitPayload;
+ }
+ if (endCondition === StreamingPaymentEndCondition.WhenCancelled) {
+ payload = whenCancelledPayload;
+ }
+ }
+
+ await editStreamingPayment(payload);
+ };
+
+ const handleEditMotion = async () => {
+ if (
+ !streamingPayment ||
+ !streamingPaymentsAddress ||
+ !votingReputationAddress
+ ) {
+ return;
+ }
+
+ const fixedPayload: StreamingPaymentsMotionEditPayload = {
+ motionDomainId: Id.RootDomain,
+ votingReputationAddress,
+ annotationMessage: annotation,
+ colony,
+ streamingPayment,
+ streamingPaymentsAddress,
+ startTimestamp: updateStartTime
+ ? getStartTime(selectedStartTime)
+ : undefined,
+ amount: updateAmount ? transactionAmount : undefined,
+ interval: updateInterval ? getInterval(selectedInterval) : undefined,
+ endCondition: StreamingPaymentEndCondition.FixedTime,
+ endTimestamp: updateEndTime ? getEndTime(selectedEndTime) : undefined,
+ };
+
+ const limitPayload: StreamingPaymentsMotionEditPayload = {
+ motionDomainId: Id.RootDomain,
+ votingReputationAddress,
+ annotationMessage: annotation,
+ colony,
+ streamingPayment,
+ streamingPaymentsAddress,
+ startTimestamp: updateStartTime
+ ? getStartTime(selectedStartTime)
+ : undefined,
+ amount: updateAmount ? transactionAmount : undefined,
+ interval: updateInterval ? getInterval(selectedInterval) : undefined,
+ endCondition: StreamingPaymentEndCondition.LimitReached,
+ limitAmount: updateLimit ? limit : undefined,
+ };
+
+ const whenCancelledPayload: StreamingPaymentsMotionEditPayload = {
+ motionDomainId: Id.RootDomain,
+ votingReputationAddress,
+ annotationMessage: annotation,
+ colony,
+ streamingPayment,
+ streamingPaymentsAddress,
+ startTimestamp: updateStartTime
+ ? getStartTime(selectedStartTime)
+ : undefined,
+ amount: updateAmount ? transactionAmount : undefined,
+ interval: updateInterval ? getInterval(selectedInterval) : undefined,
+ endCondition: StreamingPaymentEndCondition.WhenCancelled,
+ };
+
+ const undefinedEndConditionPayload: StreamingPaymentsMotionEditPayload = {
+ motionDomainId: Id.RootDomain,
+ votingReputationAddress,
+ annotationMessage: annotation,
+ colony,
+ streamingPayment,
+ streamingPaymentsAddress,
+ startTimestamp: updateStartTime
+ ? getStartTime(selectedStartTime)
+ : undefined,
+ endTimestamp: updateEndTime ? getEndTime(selectedEndTime) : undefined,
+ amount: updateAmount ? transactionAmount : undefined,
+ interval: updateInterval ? getInterval(selectedInterval) : undefined,
+ limitAmount: updateLimit ? limit : undefined,
+ };
+
+ let payload: StreamingPaymentsMotionEditPayload =
+ undefinedEndConditionPayload;
+
+ if (updateEndCondition) {
+ if (endCondition === StreamingPaymentEndCondition.FixedTime) {
+ payload = fixedPayload;
+ }
+ if (endCondition === StreamingPaymentEndCondition.LimitReached) {
+ payload = limitPayload;
+ }
+ if (endCondition === StreamingPaymentEndCondition.WhenCancelled) {
+ payload = whenCancelledPayload;
+ }
+ }
+
+ await editStreamingPaymentMotion(payload);
+ };
+
+ const createStreamingPaymentMotionPayload: StreamingPaymentsMotionCreatePayload =
+ {
+ ...createStreamingPaymentPayload,
+ motionDomainId: Id.RootDomain,
+ votingReputationAddress: votingReputationAddress ?? '',
+ annotationMessage: annotation,
+ startTimestamp: '0',
+ };
+
+ return (
+
+
+
Streaming Payments
+
+ setTokenAddress(e.currentTarget.value)}
+ value={tokenAddress}
+ label="Token Address"
+ />
+ setDecimalAmount(e.currentTarget.value)}
+ value={decimalAmount}
+ label="Token Decimals"
+ />
+ setTransactionAmount(e.currentTarget.value)}
+ value={transactionAmount}
+ label="Transaction Amount"
+ />
+ setLimit(e.currentTarget.value)}
+ value={limit}
+ label="Limit"
+ disabled={
+ endCondition !== StreamingPaymentEndCondition.LimitReached
+ }
+ />
+
+
+
+
+ setStreamingPaymentId(e.currentTarget.value)}
+ placeholder="Streaming Payment Native ID"
+ />
+
+
+ {streamingPayment && (
+
+
+ Amount claimed to date:{' '}
+
+
+
+
+
+ Available to claim:{' '}
+
+
+
+
+
+ Start time: {streamingPayment.startTime}
+
+
+ End time: {streamingPayment.endTime}
+
+
+ Amount:{' '}
+
+
+
+
+
+ Interval: {streamingPayment.interval}
+
+
+ End Condition: {streamingPayment.metadata?.endCondition}
+
+
+ Limit:{' '}
+
+ {moveDecimal(
+ getStreamingPaymentLimit({ streamingPayment }),
+ -(
+ getSelectedToken(colony, streamingPayment.tokenAddress)
+ ?.decimals || DEFAULT_TOKEN_DECIMALS
+ ),
+ )}
+
+
+
+ )}
+
+
+
+
+
+
+
+ {streamingPayment && (
+
+
+ Update start time
+ setUpdateStartTime(event.target.checked)}
+ />
+
+
+ Update end time (for fixed end condition)
+ setUpdateEndTime(event.target.checked)}
+ />
+
+
+ Update amount
+ setUpdateAmount(event.target.checked)}
+ />
+
+
+ Update interval
+ setUpdateInterval(event.target.checked)}
+ />
+
+
+ Update end condition
+
+ setUpdateEndCondition(event.target.checked)
+ }
+ />
+
+
+ Update limit (for limit reached end condition)
+ setUpdateLimit(event.target.checked)}
+ />
+
+
+
+
+ )}
+
+
+ );
+};
+
+export default TmpStreamingPayments;
diff --git a/src/components/v5/tmpDebug/context/TmpContext.ts b/src/components/v5/tmpDebug/context/TmpContext.ts
new file mode 100644
index 0000000000..cb6c4df721
--- /dev/null
+++ b/src/components/v5/tmpDebug/context/TmpContext.ts
@@ -0,0 +1,21 @@
+import { createContext, useContext } from 'react';
+
+interface TmpContextValues {
+ annotation: string;
+ setAnnotation: React.Dispatch>;
+}
+
+export const TmpContext = createContext({
+ annotation: '',
+ setAnnotation: () => {},
+});
+
+export const useTmpContext = () => {
+ const context = useContext(TmpContext);
+
+ if (context) return context;
+
+ throw new Error(
+ 'This context is only used for debug purposes and is only used on the Colony Home Page',
+ );
+};
diff --git a/src/components/v5/tmpDebug/context/TmpContextProvider.tsx b/src/components/v5/tmpDebug/context/TmpContextProvider.tsx
new file mode 100644
index 0000000000..595e5a3a57
--- /dev/null
+++ b/src/components/v5/tmpDebug/context/TmpContextProvider.tsx
@@ -0,0 +1,80 @@
+import React, { type PropsWithChildren, useState, useMemo } from 'react';
+import { useNavigate } from 'react-router-dom';
+
+import { type TransactionType } from '~redux/immutable/Transaction.ts';
+import { TX_SEARCH_PARAM } from '~routes';
+import InputBase from '~v5/common/Fields/InputBase/InputBase.tsx';
+
+import { TmpContext } from './TmpContext.ts';
+
+export const TmpContextProvider: React.FC = ({
+ children,
+}) => {
+ const [annotation, setAnnotation] = useState('');
+
+ // const { transactionAndMessageGroups } = useUserTransactionContext();
+ const transactionAndMessageGroups = [];
+
+ const navigate = useNavigate();
+
+ const value = useMemo(
+ () => ({
+ annotation,
+ setAnnotation,
+ }),
+ [annotation],
+ );
+
+ const latestTx = transactionAndMessageGroups[0]?.[0] as TransactionType;
+
+ const openTransaction = () => {
+ navigate(`${window.location.pathname}?${TX_SEARCH_PARAM}=${latestTx.hash}`);
+ };
+
+ return (
+
+
+
+
+
+ Common action form fields
+
+
+ setAnnotation(e.currentTarget.value)}
+ value={annotation}
+ label="Annotation"
+ placeholder="Enter a description"
+ />
+
+
+
+ Debug values
+
+
+
Latest Transaction
+ {latestTx && (
+
+ )}
+
+
Hash: {latestTx?.hash ?? 'null'}
+
+ Context: {latestTx?.context ?? 'null'}
+
+
+ Method name: {latestTx?.methodName}
+
+
+
+
+ {children}
+
+
+ );
+};
diff --git a/src/constants/extensions.ts b/src/constants/extensions.ts
index e634982d83..d14b979249 100644
--- a/src/constants/extensions.ts
+++ b/src/constants/extensions.ts
@@ -7,6 +7,7 @@ import ExtensionLazyConsensusIcon from '~icons/ExtensionLazyConsensusIcon.tsx';
import ExtensionMultiSigIcon from '~icons/ExtensionMultiSigIcon.tsx';
import ExtensionOneTransactionPaymentIcon from '~icons/ExtensionOneTransactionPaymentIcon.tsx';
import ExtensionStagedPaymentsIcon from '~icons/ExtensionStagedPaymentsIcon.tsx';
+import ExtensionStreamingPaymentsIcon from '~icons/ExtensionStreamingPaymentsIcon.tsx';
import multiSigHero from '~images/assets/extensions/multi-sig-hero.png';
import multiSigInterface from '~images/assets/extensions/multi-sig-interface.png';
import oneTransactionHero from '~images/assets/extensions/one-transaction-hero.png';
@@ -17,6 +18,8 @@ import stagedHero from '~images/assets/extensions/staged-hero.png';
import stagedInterface from '~images/assets/extensions/staged-interface.png';
import stakedHero from '~images/assets/extensions/staked-hero.png';
import stakedInterface from '~images/assets/extensions/staked-interface.png';
+import streamingHero from '~images/assets/extensions/streaming-hero.png';
+import streamingInterface from '~images/assets/extensions/streaming-interface.png';
import { type ExtensionConfig } from '~types/extensions.ts';
import {
convertFractionToWei,
@@ -383,18 +386,23 @@ export const supportedExtensionsConfig: ExtensionConfig[] = [
createdAt: 1692048380000,
autoEnableAfterInstall: true,
},
- // {
- // icon: ExtensionAdvancedPaymentsIcon,
- // imageURLs: [streamingHero, streamingInterface],
- // category: ExtensionCategory.Expenditures,
- // extensionId: Extension.StreamingPayments,
- // name: MSG.streamingPaymentsName,
- // descriptionShort: MSG.streamingPaymentsDescriptionShort,
- // descriptionLong: MSG.streamingPaymentsDescriptionLong,
- // neededColonyPermissions: [ColonyRole.Administration, ColonyRole.Funding],
- // uninstallable: true,
- // createdAt: 1692048380000,
- // },
+ {
+ icon: ExtensionStreamingPaymentsIcon,
+ imageURLs: [streamingHero, streamingInterface],
+ category: ExtensionCategory.Expenditures,
+ extensionId: Extension.StreamingPayments,
+ name: MSG.streamingPaymentsName,
+ descriptionShort: MSG.streamingPaymentsDescriptionShort,
+ descriptionLong: MSG.streamingPaymentsDescriptionLong,
+ neededColonyPermissions: [
+ ColonyRole.Administration,
+ ColonyRole.Funding,
+ ColonyRole.Arbitration,
+ ],
+ uninstallable: true,
+ createdAt: 1692048380000,
+ autoEnableAfterInstall: true,
+ },
{
icon: ExtensionMultiSigIcon,
imageURLs: [multiSigHero, multiSigInterface],
diff --git a/src/constants/index.ts b/src/constants/index.ts
index 50d6f69d47..7facd71db1 100644
--- a/src/constants/index.ts
+++ b/src/constants/index.ts
@@ -390,3 +390,7 @@ export const DEV_USDC_ADDRESS = import.meta.env.USDC_LOCAL_ADDRESS;
export const isFullScreen = 'isFullScreen';
export const APP_URL = new URL(import.meta.env.URL || 'http://localhost:9091/');
+
+export enum ColonyVersion {
+ V15 = 15,
+}
diff --git a/src/graphql/fragments/actions.graphql b/src/graphql/fragments/actions.graphql
index d4c4dd3b81..1a4526a6af 100644
--- a/src/graphql/fragments/actions.graphql
+++ b/src/graphql/fragments/actions.graphql
@@ -258,6 +258,9 @@ fragment ColonyMotion on ColonyMotion {
createdAt
createdBy
expenditureSlotIds
+ pendingStreamingPayment {
+ ...PendingStreamingPayment
+ }
}
fragment MotionMessage on MotionMessage {
diff --git a/src/graphql/fragments/streamingPayment.graphql b/src/graphql/fragments/streamingPayment.graphql
new file mode 100644
index 0000000000..f41a0aed25
--- /dev/null
+++ b/src/graphql/fragments/streamingPayment.graphql
@@ -0,0 +1,43 @@
+fragment StreamingPayment on StreamingPayment {
+ id
+ nativeId
+ recipientAddress
+ nativeDomainId
+ startTime
+ endTime
+ interval
+ tokenAddress
+ token {
+ ...Token
+ }
+ amount
+ metadata {
+ endCondition
+ changelog {
+ transactionHash
+ oldEndCondition
+ newEndCondition
+ }
+ }
+ claims {
+ amount
+ timestamp
+ }
+}
+
+fragment StreamingPaymentChanges on StreamingPaymentChanges {
+ startTime
+ endTime
+ interval
+ amount
+}
+
+fragment PendingStreamingPayment on PendingStreamingPayment {
+ recipientAddress
+ nativeDomainId
+ tokenAddress
+ amount
+ startTime
+ endTime
+ interval
+}
diff --git a/src/graphql/generated.ts b/src/graphql/generated.ts
index b272036b51..5424dc1bb0 100644
--- a/src/graphql/generated.ts
+++ b/src/graphql/generated.ts
@@ -340,6 +340,7 @@ export type Colony = {
roles?: Maybe;
/** Status information for the Colony */
status?: Maybe;
+ streamingPayments?: Maybe;
tokens?: Maybe;
/** Type of the Colony (Regular or Metacolony) */
type?: Maybe;
@@ -407,6 +408,16 @@ export type ColonyRolesArgs = {
};
+/** Represents a Colony within the Colony Network */
+export type ColonyStreamingPaymentsArgs = {
+ createdAt?: InputMaybe;
+ filter?: InputMaybe;
+ limit?: InputMaybe;
+ nextToken?: InputMaybe;
+ sortDirection?: InputMaybe;
+};
+
+
/** Represents a Colony within the Colony Network */
export type ColonyTokensArgs = {
filter?: InputMaybe;
@@ -538,6 +549,15 @@ export type ColonyAction = {
* Currently it is impossible to tell the reason for the action being hidden from the actions list
*/
showInActionsList: Scalars['Boolean'];
+ /** Streaming payment associated with the action, if any */
+ streamingPayment?: Maybe;
+ /**
+ * Changes to the streaming payment associated with the action, if any
+ * Applicable to `EDIT_STREAMING_PAYMENT` action only
+ */
+ streamingPaymentChanges?: Maybe;
+ /** ID of the associated streaming payment, if any */
+ streamingPaymentId?: Maybe;
/** The target Domain of the action, if applicable */
toDomain?: Maybe;
/** The target Domain identifier, if applicable */
@@ -611,12 +631,18 @@ export enum ColonyActionType {
AddVerifiedMembers = 'ADD_VERIFIED_MEMBERS',
AddVerifiedMembersMotion = 'ADD_VERIFIED_MEMBERS_MOTION',
AddVerifiedMembersMultisig = 'ADD_VERIFIED_MEMBERS_MULTISIG',
+ /** An action related to cancelling and waiving a streaming payment */
+ CancelAndWaiveStreamingPayment = 'CANCEL_AND_WAIVE_STREAMING_PAYMENT',
/** An action related to canceling an expenditure */
CancelExpenditure = 'CANCEL_EXPENDITURE',
/** An action related to a motion to cancel an expenditure */
CancelExpenditureMotion = 'CANCEL_EXPENDITURE_MOTION',
/** An action related to a multiSig to cancel a staked expenditure */
CancelStakedExpenditureMultisig = 'CANCEL_STAKED_EXPENDITURE_MULTISIG',
+ /** An action related to cancelling a streaming payment */
+ CancelStreamingPayment = 'CANCEL_STREAMING_PAYMENT',
+ /** An action related to cancelling a streaming payment via a motion */
+ CancelStreamingPaymentMotion = 'CANCEL_STREAMING_PAYMENT_MOTION',
/** An action related to editing a Colony's details */
ColonyEdit = 'COLONY_EDIT',
/** An action related to editing a Colony's details via a motion */
@@ -635,6 +661,10 @@ export enum ColonyActionType {
CreateDomainMultisig = 'CREATE_DOMAIN_MULTISIG',
/** An action related to creating an expenditure (advanced payment) */
CreateExpenditure = 'CREATE_EXPENDITURE',
+ /** An action related to creating a streaming payment */
+ CreateStreamingPayment = 'CREATE_STREAMING_PAYMENT',
+ /** An action related to creating a streaming payment via a motion */
+ CreateStreamingPaymentMotion = 'CREATE_STREAMING_PAYMENT_MOTION',
/** An action related to editing a domain's details */
EditDomain = 'EDIT_DOMAIN',
/** An action related to editing a domain's details via a motion */
@@ -645,6 +675,10 @@ export enum ColonyActionType {
EditExpenditure = 'EDIT_EXPENDITURE',
/** An action related to creating a motion to edit an expenditure */
EditExpenditureMotion = 'EDIT_EXPENDITURE_MOTION',
+ /** An action related to editing a streaming payment */
+ EditStreamingPayment = 'EDIT_STREAMING_PAYMENT',
+ /** An action related to editing a streaming payment via a motion */
+ EditStreamingPaymentMotion = 'EDIT_STREAMING_PAYMENT_MOTION',
/** An action related to a domain reputation penalty within a Colony (smite) */
EmitDomainReputationPenalty = 'EMIT_DOMAIN_REPUTATION_PENALTY',
/** An action related to a domain reputation penalty within a Colony (smite) via a motion */
@@ -1121,6 +1155,14 @@ export type ColonyMotion = {
objectionAnnotation?: Maybe;
/** Id of the associated objection annotation, if any */
objectionAnnotationId?: Maybe;
+ /** Pending streaming payment to be created by motion, if any */
+ pendingStreamingPayment?: Maybe;
+ /** Streaming Payment changes by the action */
+ pendingStreamingPaymentChanges?: Maybe;
+ /** Streaming payment metadata that is stored temporarily and committed to the database once the corresponding motion passes */
+ pendingStreamingPaymentMetadata?: Maybe;
+ /** Identifier of streaming payment metadata that is stored temporarily and committed to the database once the corresponding motion passes */
+ pendingStreamingPaymentMetadataId?: Maybe;
/**
* Stakes remaining to activate either side of the motion
* It's a tuple: `[nayRemaining, yayRemaining]`
@@ -1136,6 +1178,10 @@ export type ColonyMotion = {
skillRep: Scalars['String'];
/** List of staker rewards users will be receiving for a motion */
stakerRewards: Array;
+ /** Streaming payment associated with the action, if any */
+ streamingPayment?: Maybe;
+ /** ID of the associated streaming payment, if any */
+ streamingPaymentId?: Maybe;
/** The transaction hash of the createMotion action */
transactionHash: Scalars['ID'];
updatedAt: Scalars['AWSDateTime'];
@@ -1472,6 +1518,8 @@ export type CreateColonyActionInput = {
rolesAreMultiSig?: InputMaybe;
rootHash: Scalars['String'];
showInActionsList: Scalars['Boolean'];
+ streamingPaymentChanges?: InputMaybe;
+ streamingPaymentId?: InputMaybe;
toDomainId?: InputMaybe;
toPotId?: InputMaybe;
tokenAddress?: InputMaybe;
@@ -1623,12 +1671,16 @@ export type CreateColonyMotionInput = {
nativeMotionDomainId: Scalars['String'];
nativeMotionId: Scalars['String'];
objectionAnnotationId?: InputMaybe;
+ pendingStreamingPayment?: InputMaybe;
+ pendingStreamingPaymentChanges?: InputMaybe;
+ pendingStreamingPaymentMetadataId?: InputMaybe;
remainingStakes: Array;
repSubmitted: Scalars['String'];
requiredStake: Scalars['String'];
revealedVotes: MotionStakesInput;
skillRep: Scalars['String'];
stakerRewards: Array;
+ streamingPaymentId?: InputMaybe;
transactionHash: Scalars['ID'];
userMinStake: Scalars['String'];
usersStakes: Array;
@@ -1864,21 +1916,27 @@ export type CreateSafeTransactionInput = {
};
export type CreateStreamingPaymentInput = {
+ amount: Scalars['String'];
+ claims?: InputMaybe>;
+ colonyId: Scalars['ID'];
createdAt?: InputMaybe;
- endTime: Scalars['AWSTimestamp'];
+ creatorAddress: Scalars['ID'];
+ endTime: Scalars['String'];
id?: InputMaybe;
interval: Scalars['String'];
+ isCancelled?: InputMaybe;
+ isWaived?: InputMaybe;
nativeDomainId: Scalars['Int'];
nativeId: Scalars['Int'];
- payouts?: InputMaybe>;
recipientAddress: Scalars['String'];
- startTime: Scalars['AWSTimestamp'];
+ startTime: Scalars['String'];
+ tokenAddress: Scalars['ID'];
};
export type CreateStreamingPaymentMetadataInput = {
+ changelog?: InputMaybe>;
endCondition: StreamingPaymentEndCondition;
id?: InputMaybe;
- limitAmount?: InputMaybe;
};
export type CreateTokenExchangeRateInput = {
@@ -2922,6 +2980,7 @@ export type ModelColonyActionConditionInput = {
rolesAreMultiSig?: InputMaybe;
rootHash?: InputMaybe;
showInActionsList?: InputMaybe;
+ streamingPaymentId?: InputMaybe;
toDomainId?: InputMaybe;
toPotId?: InputMaybe;
tokenAddress?: InputMaybe;
@@ -2968,6 +3027,7 @@ export type ModelColonyActionFilterInput = {
rolesAreMultiSig?: InputMaybe;
rootHash?: InputMaybe;
showInActionsList?: InputMaybe;
+ streamingPaymentId?: InputMaybe;
toDomainId?: InputMaybe;
toPotId?: InputMaybe;
tokenAddress?: InputMaybe;
@@ -3282,10 +3342,12 @@ export type ModelColonyMotionConditionInput = {
not?: InputMaybe;
objectionAnnotationId?: InputMaybe;
or?: InputMaybe>>;
+ pendingStreamingPaymentMetadataId?: InputMaybe;
remainingStakes?: InputMaybe;
repSubmitted?: InputMaybe;
requiredStake?: InputMaybe;
skillRep?: InputMaybe;
+ streamingPaymentId?: InputMaybe;
transactionHash?: InputMaybe;
userMinStake?: InputMaybe;
};
@@ -3311,10 +3373,12 @@ export type ModelColonyMotionFilterInput = {
not?: InputMaybe;
objectionAnnotationId?: InputMaybe;
or?: InputMaybe>>;
+ pendingStreamingPaymentMetadataId?: InputMaybe;
remainingStakes?: InputMaybe;
repSubmitted?: InputMaybe;
requiredStake?: InputMaybe;
skillRep?: InputMaybe;
+ streamingPaymentId?: InputMaybe;
transactionHash?: InputMaybe;
userMinStake?: InputMaybe;
};
@@ -4114,16 +4178,22 @@ export type ModelSplitPaymentDistributionTypeInput = {
};
export type ModelStreamingPaymentConditionInput = {
+ amount?: InputMaybe;
and?: InputMaybe>>;
+ colonyId?: InputMaybe;
createdAt?: InputMaybe;
- endTime?: InputMaybe;
+ creatorAddress?: InputMaybe;
+ endTime?: InputMaybe;
interval?: InputMaybe;
+ isCancelled?: InputMaybe;
+ isWaived?: InputMaybe;
nativeDomainId?: InputMaybe;
nativeId?: InputMaybe;
not?: InputMaybe;
or?: InputMaybe>>;
recipientAddress?: InputMaybe;
- startTime?: InputMaybe;
+ startTime?: InputMaybe;
+ tokenAddress?: InputMaybe;
};
export type ModelStreamingPaymentConnection = {
@@ -4138,23 +4208,28 @@ export type ModelStreamingPaymentEndConditionInput = {
};
export type ModelStreamingPaymentFilterInput = {
+ amount?: InputMaybe;
and?: InputMaybe>>;
+ colonyId?: InputMaybe;
createdAt?: InputMaybe;
- endTime?: InputMaybe;
+ creatorAddress?: InputMaybe;
+ endTime?: InputMaybe;
id?: InputMaybe;
interval?: InputMaybe;
+ isCancelled?: InputMaybe;
+ isWaived?: InputMaybe;
nativeDomainId?: InputMaybe;
nativeId?: InputMaybe;
not?: InputMaybe;
or?: InputMaybe>>;
recipientAddress?: InputMaybe;
- startTime?: InputMaybe;
+ startTime?: InputMaybe;
+ tokenAddress?: InputMaybe;
};
export type ModelStreamingPaymentMetadataConditionInput = {
and?: InputMaybe>>;
endCondition?: InputMaybe;
- limitAmount?: InputMaybe;
not?: InputMaybe;
or?: InputMaybe>>;
};
@@ -4169,7 +4244,6 @@ export type ModelStreamingPaymentMetadataFilterInput = {
and?: InputMaybe>>;
endCondition?: InputMaybe;
id?: InputMaybe;
- limitAmount?: InputMaybe;
not?: InputMaybe;
or?: InputMaybe>>;
};
@@ -4260,6 +4334,7 @@ export type ModelSubscriptionColonyActionFilterInput = {
rolesAreMultiSig?: InputMaybe;
rootHash?: InputMaybe;
showInActionsList?: InputMaybe;
+ streamingPaymentId?: InputMaybe;
toDomainId?: InputMaybe;
toPotId?: InputMaybe;
tokenAddress?: InputMaybe;
@@ -4392,10 +4467,12 @@ export type ModelSubscriptionColonyMotionFilterInput = {
nativeMotionId?: InputMaybe;
objectionAnnotationId?: InputMaybe;
or?: InputMaybe>>;
+ pendingStreamingPaymentMetadataId?: InputMaybe;
remainingStakes?: InputMaybe;
repSubmitted?: InputMaybe;
requiredStake?: InputMaybe;
skillRep?: InputMaybe;
+ streamingPaymentId?: InputMaybe;
transactionHash?: InputMaybe;
userMinStake?: InputMaybe;
};
@@ -4693,23 +4770,28 @@ export type ModelSubscriptionSafeTransactionFilterInput = {
};
export type ModelSubscriptionStreamingPaymentFilterInput = {
+ amount?: InputMaybe;
and?: InputMaybe>>;
+ colonyId?: InputMaybe;
createdAt?: InputMaybe;
- endTime?: InputMaybe;
+ creatorAddress?: InputMaybe;
+ endTime?: InputMaybe;
id?: InputMaybe;
interval?: InputMaybe;
+ isCancelled?: InputMaybe;
+ isWaived?: InputMaybe;
nativeDomainId?: InputMaybe;
nativeId?: InputMaybe;
or?: InputMaybe>>;
recipientAddress?: InputMaybe;
- startTime?: InputMaybe;
+ startTime?: InputMaybe;
+ tokenAddress?: InputMaybe;
};
export type ModelSubscriptionStreamingPaymentMetadataFilterInput = {
and?: InputMaybe>>;
endCondition?: InputMaybe;
id?: InputMaybe;
- limitAmount?: InputMaybe;
or?: InputMaybe>>;
};
@@ -6539,6 +6621,34 @@ export type PaymentInput = {
tokenAddress: Scalars['String'];
};
+export type PendingStreamingPayment = {
+ __typename?: 'PendingStreamingPayment';
+ /** Amount per interval */
+ amount: Scalars['String'];
+ /** End time in seconds since epoch */
+ endTime: Scalars['String'];
+ /** Payment interval in seconds */
+ interval: Scalars['String'];
+ /** Native domain ID where the streaming payment will be created */
+ nativeDomainId: Scalars['Int'];
+ /** Address of the recipient */
+ recipientAddress: Scalars['String'];
+ /** Start time in seconds since epoch */
+ startTime: Scalars['String'];
+ /** Token address used for payments */
+ tokenAddress: Scalars['ID'];
+};
+
+export type PendingStreamingPaymentInput = {
+ amount: Scalars['String'];
+ endTime: Scalars['String'];
+ interval: Scalars['String'];
+ nativeDomainId: Scalars['Int'];
+ recipientAddress: Scalars['String'];
+ startTime: Scalars['String'];
+ tokenAddress: Scalars['ID'];
+};
+
export type PrivateBetaInviteCode = {
__typename?: 'PrivateBetaInviteCode';
createdAt: Scalars['AWSDateTime'];
@@ -6650,6 +6760,7 @@ export type Query = {
cacheAllDomainBalance?: Maybe;
cacheTotalBalanceByColonyAddress?: Maybe;
getActionByExpenditureId?: Maybe;
+ getActionByStreamingPaymentId?: Maybe;
getActionsByColony?: Maybe;
getAnnotation?: Maybe;
getCacheTotalBalance?: Maybe;
@@ -6701,6 +6812,7 @@ export type Query = {
getLiquidationAddress?: Maybe;
getLiquidationAddressesByUserAddress?: Maybe;
getMotionByExpenditureId?: Maybe;
+ getMotionByStreamingPaymentId?: Maybe;
getMotionByTransactionHash?: Maybe;
getMotionMessage?: Maybe;
getMotionMessageByMotionId?: Maybe;
@@ -6728,6 +6840,7 @@ export type Query = {
getSafeTransactionStatus?: Maybe>;
getStreamingPayment?: Maybe;
getStreamingPaymentMetadata?: Maybe;
+ getStreamingPaymentsByColony?: Maybe;
getToken?: Maybe;
getTokenByAddress?: Maybe;
getTokenExchangeRate?: Maybe;
@@ -6801,6 +6914,7 @@ export type Query = {
listVoterRewardsHistories?: Maybe;
searchColonyActions?: Maybe;
searchColonyContributors?: Maybe;
+ searchStreamingPayments?: Maybe;
tokenExhangeRateByTokenId?: Maybe;
};
@@ -6832,6 +6946,16 @@ export type QueryGetActionByExpenditureIdArgs = {
};
+/** Root query type */
+export type QueryGetActionByStreamingPaymentIdArgs = {
+ filter?: InputMaybe;
+ limit?: InputMaybe;
+ nextToken?: InputMaybe;
+ sortDirection?: InputMaybe;
+ streamingPaymentId: Scalars['ID'];
+};
+
+
/** Root query type */
export type QueryGetActionsByColonyArgs = {
colonyId: Scalars['ID'];
@@ -7231,6 +7355,16 @@ export type QueryGetMotionByExpenditureIdArgs = {
};
+/** Root query type */
+export type QueryGetMotionByStreamingPaymentIdArgs = {
+ filter?: InputMaybe;
+ limit?: InputMaybe;
+ nextToken?: InputMaybe;
+ sortDirection?: InputMaybe;
+ streamingPaymentId: Scalars['ID'];
+};
+
+
/** Root query type */
export type QueryGetMotionByTransactionHashArgs = {
filter?: InputMaybe;
@@ -7434,6 +7568,17 @@ export type QueryGetStreamingPaymentMetadataArgs = {
};
+/** Root query type */
+export type QueryGetStreamingPaymentsByColonyArgs = {
+ colonyId: Scalars['ID'];
+ createdAt?: InputMaybe;
+ filter?: InputMaybe;
+ limit?: InputMaybe;
+ nextToken?: InputMaybe;
+ sortDirection?: InputMaybe;
+};
+
+
/** Root query type */
export type QueryGetTokenArgs = {
id: Scalars['ID'];
@@ -7981,6 +8126,17 @@ export type QuerySearchColonyContributorsArgs = {
};
+/** Root query type */
+export type QuerySearchStreamingPaymentsArgs = {
+ aggregates?: InputMaybe>>;
+ filter?: InputMaybe;
+ from?: InputMaybe;
+ limit?: InputMaybe;
+ nextToken?: InputMaybe;
+ sort?: InputMaybe>>;
+};
+
+
/** Root query type */
export type QueryTokenExhangeRateByTokenIdArgs = {
date?: InputMaybe;
@@ -8129,6 +8285,7 @@ export enum SearchableColonyActionAggregateField {
RolesAreMultiSig = 'rolesAreMultiSig',
RootHash = 'rootHash',
ShowInActionsList = 'showInActionsList',
+ StreamingPaymentId = 'streamingPaymentId',
ToDomainId = 'toDomainId',
ToPotId = 'toPotId',
TokenAddress = 'tokenAddress',
@@ -8184,6 +8341,7 @@ export type SearchableColonyActionFilterInput = {
rolesAreMultiSig?: InputMaybe;
rootHash?: InputMaybe;
showInActionsList?: InputMaybe;
+ streamingPaymentId?: InputMaybe;
toDomainId?: InputMaybe;
toPotId?: InputMaybe;
tokenAddress?: InputMaybe;
@@ -8227,6 +8385,7 @@ export enum SearchableColonyActionSortableFields {
RolesAreMultiSig = 'rolesAreMultiSig',
RootHash = 'rootHash',
ShowInActionsList = 'showInActionsList',
+ StreamingPaymentId = 'streamingPaymentId',
ToDomainId = 'toDomainId',
ToPotId = 'toPotId',
TokenAddress = 'tokenAddress',
@@ -8338,6 +8497,82 @@ export enum SearchableSortDirection {
Desc = 'desc'
}
+export enum SearchableStreamingPaymentAggregateField {
+ Amount = 'amount',
+ ColonyId = 'colonyId',
+ CreatedAt = 'createdAt',
+ CreatorAddress = 'creatorAddress',
+ EndTime = 'endTime',
+ Id = 'id',
+ Interval = 'interval',
+ IsCancelled = 'isCancelled',
+ IsWaived = 'isWaived',
+ NativeDomainId = 'nativeDomainId',
+ NativeId = 'nativeId',
+ RecipientAddress = 'recipientAddress',
+ StartTime = 'startTime',
+ TokenAddress = 'tokenAddress',
+ UpdatedAt = 'updatedAt'
+}
+
+export type SearchableStreamingPaymentAggregationInput = {
+ field: SearchableStreamingPaymentAggregateField;
+ name: Scalars['String'];
+ type: SearchableAggregateType;
+};
+
+export type SearchableStreamingPaymentConnection = {
+ __typename?: 'SearchableStreamingPaymentConnection';
+ aggregateItems: Array>;
+ items: Array>;
+ nextToken?: Maybe;
+ total?: Maybe;
+};
+
+export type SearchableStreamingPaymentFilterInput = {
+ amount?: InputMaybe;
+ and?: InputMaybe>>;
+ colonyId?: InputMaybe;
+ createdAt?: InputMaybe;
+ creatorAddress?: InputMaybe;
+ endTime?: InputMaybe;
+ id?: InputMaybe;
+ interval?: InputMaybe;
+ isCancelled?: InputMaybe;
+ isWaived?: InputMaybe;
+ nativeDomainId?: InputMaybe;
+ nativeId?: InputMaybe;
+ not?: InputMaybe;
+ or?: InputMaybe>>;
+ recipientAddress?: InputMaybe;
+ startTime?: InputMaybe;
+ tokenAddress?: InputMaybe;
+ updatedAt?: InputMaybe;
+};
+
+export type SearchableStreamingPaymentSortInput = {
+ direction?: InputMaybe