diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Asset Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru similarity index 88% rename from bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Asset Liquidity.bru rename to bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru index 9d3a0ba5ba..3ee4d48766 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Asset Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Asset Liquidity Withdrawal.bru @@ -27,7 +27,8 @@ body:graphql:vars { "id": "{{transferId}}", "assetId": "{{assetId}}", "amount": "100", - "idempotencyKey":"{{idempotencyKey}}" + "idempotencyKey":"{{idempotencyKey}}", + "timeoutSeconds": {{withdrawalTimeout}} } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Incoming Payment Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru similarity index 69% rename from bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Incoming Payment Liquidity.bru rename to bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru index 84d6e1ca88..97752f81f3 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Incoming Payment Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Incoming Payment Withdrawal.bru @@ -11,8 +11,8 @@ post { } body:graphql { - mutation WithdrawIncomingPaymentLiquidity($input: WithdrawIncomingPaymentLiquidityInput!) { - withdrawIncomingPaymentLiquidity(input: $input) { + mutation CreateIncomingPaymentWithdrawal($input: CreateIncomingPaymentWithdrawalInput!) { + createIncomingPaymentWithdrawal(input: $input) { code error message @@ -25,7 +25,8 @@ body:graphql:vars { { "input": { "incomingPaymentId": "{{incomingPaymentId}}", - "idempotencyKey":"{{idempotencyKey}}" + "idempotencyKey": "{{idempotencyKey}}", + "timeoutSeconds": {{withdrawalTimeout}} } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Outgoing Payment Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru similarity index 69% rename from bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Outgoing Payment Liquidity.bru rename to bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru index a2f547a72f..832a1ae9f7 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Outgoing Payment Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Outgoing Payment Withdrawal.bru @@ -11,8 +11,8 @@ post { } body:graphql { - mutation WithdrawOutgoingPaymentLiquidity($input: WithdrawOutgoingPaymentLiquidityInput!) { - withdrawOutgoingPaymentLiquidity(input: $input) { + mutation CreateOutgoingPaymentWithdrawal($input: CreateOutgoingPaymentWithdrawalInput!) { + createOutgoingPaymentWithdrawal(input: $input) { code error message @@ -25,7 +25,8 @@ body:graphql:vars { { "input": { "outgoingPaymentId": "{{outgoingPaymentId}}", - "idempotencyKey":"{{idempotencyKey}}" + "idempotencyKey": "{{idempotencyKey}}", + "timeoutSeconds": {{withdrawalTimeout}} } } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Peer Liquidity.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru similarity index 88% rename from bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Peer Liquidity.bru rename to bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru index 145065ea81..d11e557709 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Withdraw Peer Liquidity.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Peer Liquidity Withdrawal.bru @@ -27,7 +27,8 @@ body:graphql:vars { "id": "{{withdrawalId}}", "peerId": "{{peerId}}", "amount": "100", - "idempotencyKey":"{{idempotencyKey}}" + "idempotencyKey":"{{idempotencyKey}}", + "timeoutSeconds": {{withdrawalTimeout}} } } diff --git a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Withdrawal.bru b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Withdrawal.bru index 04cd906cbc..ff377ab90a 100644 --- a/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Withdrawal.bru +++ b/bruno/collections/Rafiki/Rafiki Admin APIs/Create Wallet Address Withdrawal.bru @@ -40,7 +40,8 @@ body:graphql:vars { "input": { "id": "02ac56f7-ae5d-4abb-8306-17bf2327b43c", "walletAddressId": "{{walletAddressId}}", - "idempotencyKey":"{{idempotencyKey}}" + "idempotencyKey":"{{idempotencyKey}}", + "timeoutSeconds": {{withdrawalTimeout}} } } } diff --git a/bruno/collections/Rafiki/environments/Autopeering.bru b/bruno/collections/Rafiki/environments/Autopeering.bru index a9202702b2..50a8667b2d 100644 --- a/bruno/collections/Rafiki/environments/Autopeering.bru +++ b/bruno/collections/Rafiki/environments/Autopeering.bru @@ -5,4 +5,5 @@ vars { receiverWalletAddress: https://ilp.rafiki.money/d99f0eee signatureUrl: https://kxu5d4mr4blcthphxomjlc4xk40rvdsx.lambda-url.eu-central-1.on.aws/ clientPrivateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1DNENBUUF3QlFZREsyVndCQ0lFSUUvMmFwQXduMlJPek5WNWd1L2ltZzdpT05rOWE1Ui9yakFxWVlUWHozZzgKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQ== + withdrawalTimeout: 60 } diff --git a/bruno/collections/Rafiki/environments/Local Playground.bru b/bruno/collections/Rafiki/environments/Local Playground.bru index ff4049b712..4f3e437e29 100644 --- a/bruno/collections/Rafiki/environments/Local Playground.bru +++ b/bruno/collections/Rafiki/environments/Local Playground.bru @@ -22,4 +22,5 @@ vars { asmithWalletAddress: https://happy-life-bank-backend/accounts/asmith larsWalletAddress: https://happy-life-bank-backend/accounts/lars davidWalletAddress: https://happy-life-bank-backend/accounts/david + withdrawalTimeout: 60 } diff --git a/bruno/collections/Rafiki/environments/Remote.bru b/bruno/collections/Rafiki/environments/Remote.bru index 9251a66d8f..e555872f04 100644 --- a/bruno/collections/Rafiki/environments/Remote.bru +++ b/bruno/collections/Rafiki/environments/Remote.bru @@ -5,4 +5,5 @@ vars { receiverWalletAddress: https://ilp.rafiki.money/f1475476 signatureUrl: https://kxu5d4mr4blcthphxomjlc4xk40rvdsx.lambda-url.eu-central-1.on.aws/ clientPrivateKey: LS0tLS1CRUdJTiBQUklWQVRFIEtFWS0tLS0tCk1DNENBUUF3QlFZREsyVndCQ0lFSUUvMmFwQXduMlJPek5WNWd1L2ltZzdpT05rOWE1Ui9yakFxWVlUWHozZzgKLS0tLS1FTkQgUFJJVkFURSBLRVktLS0tLQ== + withdrawalTimeout: 60 } diff --git a/localenv/README.md b/localenv/README.md index f88d8c6989..5bf0dd0652 100644 --- a/localenv/README.md +++ b/localenv/README.md @@ -97,6 +97,9 @@ pnpm localenv:compose up // tear down and remove volumes pnpm localenv:compose down --volumes + +// tear down, delete database volumes and remove images +pnpm localenv:compose down --volumes --rmi all ``` If you want to use Postgres as the accounting database instead of TigerBeetle, you can use the `psql` variant of the `localenv:compose` commands: @@ -114,6 +117,8 @@ The secondary Happy Life Bank docker compose file (`./happy-life-bank/docker-com data stores created by the primary Rafiki instance so it can't be run by itself. The `pnpm localenv:compose up` command starts both the primary instance and the secondary. +See the `frontend` [README](../packages/frontend/README.md#ory-kratos) for more information regarding the Ory Kratos identity and user management system required for Admin UI. + #### Autopeering If you want to start the local env and peer it automatically to rafiki.money, you can run the following commands: @@ -147,6 +152,9 @@ pnpm localenv:compose down // tear down and delete database volumes pnpm localenv:compose down --volumes + +// tear down, delete database volumes and remove images +pnpm localenv:compose down --volumes --rmi all ``` ### Commands diff --git a/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts b/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts index 30f5035096..28f46af534 100644 --- a/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts +++ b/localenv/mock-account-servicing-entity/app/lib/webhooks.server.ts @@ -155,10 +155,10 @@ export async function handleIncomingPaymentCompletedExpired(wh: Webhook) { await apolloClient .mutate({ mutation: gql` - mutation WithdrawIncomingPaymentLiquidity( - $input: WithdrawIncomingPaymentLiquidityInput! + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! ) { - withdrawIncomingPaymentLiquidity(input: $input) { + createIncomingPaymentWithdrawal(input: $input) { code success message @@ -169,13 +169,14 @@ export async function handleIncomingPaymentCompletedExpired(wh: Webhook) { variables: { input: { incomingPaymentId: payment.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawIncomingPaymentLiquidity + return query.data.createIncomingPaymentWithdrawal } else { throw new Error('Data was empty') } diff --git a/localenv/mock-account-servicing-entity/generated/graphql.ts b/localenv/mock-account-servicing-entity/generated/graphql.ts index 61ebb6868b..0de5e4b8f0 100644 --- a/localenv/mock-account-servicing-entity/generated/graphql.ts +++ b/localenv/mock-account-servicing-entity/generated/graphql.ts @@ -130,6 +130,8 @@ export type CreateAssetLiquidityWithdrawalInput = { id: Scalars['String']['input']; /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; }; export type CreateIncomingPaymentInput = { @@ -145,6 +147,15 @@ export type CreateIncomingPaymentInput = { walletAddressId: Scalars['String']['input']; }; +export type CreateIncomingPaymentWithdrawalInput = { + /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ + idempotencyKey: Scalars['String']['input']; + /** The id of the incoming payment to withdraw from. */ + incomingPaymentId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; +}; + export type CreateOrUpdatePeerByUrlInput = { /** Asset id of peering relationship */ assetId: Scalars['String']['input']; @@ -194,6 +205,15 @@ export type CreateOutgoingPaymentInput = { walletAddressId: Scalars['String']['input']; }; +export type CreateOutgoingPaymentWithdrawalInput = { + /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ + idempotencyKey: Scalars['String']['input']; + /** The id of the outgoing payment to withdraw from. */ + outgoingPaymentId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; +}; + export type CreatePeerInput = { /** Asset id of peering relationship */ assetId: Scalars['String']['input']; @@ -222,6 +242,8 @@ export type CreatePeerLiquidityWithdrawalInput = { idempotencyKey: Scalars['String']['input']; /** The id of the peer to create the withdrawal for. */ peerId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; }; export type CreatePeerMutationResponse = MutationResponse & { @@ -306,6 +328,8 @@ export type CreateWalletAddressWithdrawalInput = { id: Scalars['String']['input']; /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; /** The id of the Open Payments wallet address to create the withdrawal for. */ walletAddressId: Scalars['String']['input']; }; @@ -566,12 +590,16 @@ export type Mutation = { createAssetLiquidityWithdrawal?: Maybe; /** Create an internal Open Payments Incoming Payment. The receiver has a wallet address on this Rafiki instance. */ createIncomingPayment: IncomingPaymentResponse; + /** Withdraw incoming payment liquidity */ + createIncomingPaymentWithdrawal?: Maybe; /** Create a peer using a URL */ createOrUpdatePeerByUrl: CreateOrUpdatePeerByUrlMutationResponse; /** Create an Open Payments Outgoing Payment */ createOutgoingPayment: OutgoingPaymentResponse; /** Create an Open Payments Outgoing Payment from an incoming payment */ createOutgoingPaymentFromIncomingPayment: OutgoingPaymentResponse; + /** Withdraw outgoing payment liquidity */ + createOutgoingPaymentWithdrawal?: Maybe; /** Create a peer */ createPeer: CreatePeerMutationResponse; /** Withdraw peer liquidity */ @@ -617,13 +645,9 @@ export type Mutation = { voidLiquidityWithdrawal?: Maybe; /** * Withdraw webhook event liquidity - * @deprecated Use `withdrawOutgoingPaymentLiquidity, withdrawIncomingPaymentLiquidity, or createWalletAddressWithdrawal` + * @deprecated Use `createOutgoingPaymentWithdrawal, createIncomingPaymentWithdrawal, or createWalletAddressWithdrawal` */ withdrawEventLiquidity?: Maybe; - /** Withdraw incoming payment liquidity */ - withdrawIncomingPaymentLiquidity?: Maybe; - /** Withdraw outgoing payment liquidity */ - withdrawOutgoingPaymentLiquidity?: Maybe; }; @@ -647,6 +671,11 @@ export type MutationCreateIncomingPaymentArgs = { }; +export type MutationCreateIncomingPaymentWithdrawalArgs = { + input: CreateIncomingPaymentWithdrawalInput; +}; + + export type MutationCreateOrUpdatePeerByUrlArgs = { input: CreateOrUpdatePeerByUrlInput; }; @@ -662,6 +691,11 @@ export type MutationCreateOutgoingPaymentFromIncomingPaymentArgs = { }; +export type MutationCreateOutgoingPaymentWithdrawalArgs = { + input: CreateOutgoingPaymentWithdrawalInput; +}; + + export type MutationCreatePeerArgs = { input: CreatePeerInput; }; @@ -766,16 +800,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; - -export type MutationWithdrawIncomingPaymentLiquidityArgs = { - input: WithdrawIncomingPaymentLiquidityInput; -}; - - -export type MutationWithdrawOutgoingPaymentLiquidityArgs = { - input: WithdrawOutgoingPaymentLiquidityInput; -}; - export type MutationResponse = { code: Scalars['String']['output']; message: Scalars['String']['output']; @@ -1404,20 +1428,6 @@ export type WithdrawEventLiquidityInput = { idempotencyKey: Scalars['String']['input']; }; -export type WithdrawIncomingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the incoming payment to withdraw from. */ - incomingPaymentId: Scalars['String']['input']; -}; - -export type WithdrawOutgoingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the outgoing payment to withdraw from. */ - outgoingPaymentId: Scalars['String']['input']; -}; - export type ResolverTypeWrapper = Promise | T; @@ -1508,10 +1518,12 @@ export type ResolversTypes = { CreateAssetInput: ResolverTypeWrapper>; CreateAssetLiquidityWithdrawalInput: ResolverTypeWrapper>; CreateIncomingPaymentInput: ResolverTypeWrapper>; + CreateIncomingPaymentWithdrawalInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlMutationResponse: ResolverTypeWrapper>; CreateOutgoingPaymentFromIncomingPaymentInput: ResolverTypeWrapper>; CreateOutgoingPaymentInput: ResolverTypeWrapper>; + CreateOutgoingPaymentWithdrawalInput: ResolverTypeWrapper>; CreatePeerInput: ResolverTypeWrapper>; CreatePeerLiquidityWithdrawalInput: ResolverTypeWrapper>; CreatePeerMutationResponse: ResolverTypeWrapper>; @@ -1610,8 +1622,6 @@ export type ResolversTypes = { WebhookEventsConnection: ResolverTypeWrapper>; WebhookEventsEdge: ResolverTypeWrapper>; WithdrawEventLiquidityInput: ResolverTypeWrapper>; - WithdrawIncomingPaymentLiquidityInput: ResolverTypeWrapper>; - WithdrawOutgoingPaymentLiquidityInput: ResolverTypeWrapper>; }; /** Mapping between all available schema types and the resolvers parents */ @@ -1628,10 +1638,12 @@ export type ResolversParentTypes = { CreateAssetInput: Partial; CreateAssetLiquidityWithdrawalInput: Partial; CreateIncomingPaymentInput: Partial; + CreateIncomingPaymentWithdrawalInput: Partial; CreateOrUpdatePeerByUrlInput: Partial; CreateOrUpdatePeerByUrlMutationResponse: Partial; CreateOutgoingPaymentFromIncomingPaymentInput: Partial; CreateOutgoingPaymentInput: Partial; + CreateOutgoingPaymentWithdrawalInput: Partial; CreatePeerInput: Partial; CreatePeerLiquidityWithdrawalInput: Partial; CreatePeerMutationResponse: Partial; @@ -1721,8 +1733,6 @@ export type ResolversParentTypes = { WebhookEventsConnection: Partial; WebhookEventsEdge: Partial; WithdrawEventLiquidityInput: Partial; - WithdrawIncomingPaymentLiquidityInput: Partial; - WithdrawOutgoingPaymentLiquidityInput: Partial; }; export type AmountResolvers = { @@ -1921,9 +1931,11 @@ export type MutationResolvers>; createAssetLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createIncomingPayment?: Resolver>; + createIncomingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createOrUpdatePeerByUrl?: Resolver>; createOutgoingPayment?: Resolver>; createOutgoingPaymentFromIncomingPayment?: Resolver>; + createOutgoingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createPeer?: Resolver>; createPeerLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createQuote?: Resolver>; @@ -1945,8 +1957,6 @@ export type MutationResolvers>; voidLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; withdrawEventLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawIncomingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawOutgoingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; }; export type MutationResponseResolvers = { diff --git a/packages/backend/src/graphql/generated/graphql.schema.json b/packages/backend/src/graphql/generated/graphql.schema.json index 1d3fdf6c38..37c62f910a 100644 --- a/packages/backend/src/graphql/generated/graphql.schema.json +++ b/packages/backend/src/graphql/generated/graphql.schema.json @@ -824,6 +824,22 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "timeoutSeconds", + "description": "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "UInt64", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "interfaces": null, @@ -905,6 +921,65 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "CreateIncomingPaymentWithdrawalInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "idempotencyKey", + "description": "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "incomingPaymentId", + "description": "The id of the incoming payment to withdraw from.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "timeoutSeconds", + "description": "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "UInt64", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "CreateOrUpdatePeerByUrlInput", @@ -1235,6 +1310,65 @@ "enumValues": null, "possibleTypes": null }, + { + "kind": "INPUT_OBJECT", + "name": "CreateOutgoingPaymentWithdrawalInput", + "description": null, + "fields": null, + "inputFields": [ + { + "name": "idempotencyKey", + "description": "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "outgoingPaymentId", + "description": "The id of the outgoing payment to withdraw from.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "String", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, + { + "name": "timeoutSeconds", + "description": "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "UInt64", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "interfaces": null, + "enumValues": null, + "possibleTypes": null + }, { "kind": "INPUT_OBJECT", "name": "CreatePeerInput", @@ -1423,6 +1557,22 @@ "defaultValue": null, "isDeprecated": false, "deprecationReason": null + }, + { + "name": "timeoutSeconds", + "description": "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "UInt64", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null } ], "interfaces": null, @@ -2041,6 +2191,22 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "timeoutSeconds", + "description": "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer.", + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "SCALAR", + "name": "UInt64", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "walletAddressId", "description": "The id of the Open Payments wallet address to create the withdrawal for.", @@ -3897,6 +4063,35 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "createIncomingPaymentWithdrawal", + "description": "Withdraw incoming payment liquidity", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CreateIncomingPaymentWithdrawalInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "LiquidityMutationResponse", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "createOrUpdatePeerByUrl", "description": "Create a peer using a URL", @@ -3996,6 +4191,35 @@ "isDeprecated": false, "deprecationReason": null }, + { + "name": "createOutgoingPaymentWithdrawal", + "description": "Withdraw outgoing payment liquidity", + "args": [ + { + "name": "input", + "description": null, + "type": { + "kind": "NON_NULL", + "name": null, + "ofType": { + "kind": "INPUT_OBJECT", + "name": "CreateOutgoingPaymentWithdrawalInput", + "ofType": null + } + }, + "defaultValue": null, + "isDeprecated": false, + "deprecationReason": null + } + ], + "type": { + "kind": "OBJECT", + "name": "LiquidityMutationResponse", + "ofType": null + }, + "isDeprecated": false, + "deprecationReason": null + }, { "name": "createPeer", "description": "Create a peer", @@ -4643,65 +4867,7 @@ "ofType": null }, "isDeprecated": true, - "deprecationReason": "Use `withdrawOutgoingPaymentLiquidity, withdrawIncomingPaymentLiquidity, or createWalletAddressWithdrawal`" - }, - { - "name": "withdrawIncomingPaymentLiquidity", - "description": "Withdraw incoming payment liquidity", - "args": [ - { - "name": "input", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "INPUT_OBJECT", - "name": "WithdrawIncomingPaymentLiquidityInput", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "LiquidityMutationResponse", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "withdrawOutgoingPaymentLiquidity", - "description": "Withdraw outgoing payment liquidity", - "args": [ - { - "name": "input", - "description": null, - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "INPUT_OBJECT", - "name": "WithdrawOutgoingPaymentLiquidityInput", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "type": { - "kind": "OBJECT", - "name": "LiquidityMutationResponse", - "ofType": null - }, - "isDeprecated": false, - "deprecationReason": null + "deprecationReason": "Use `createOutgoingPaymentWithdrawal, createIncomingPaymentWithdrawal, or createWalletAddressWithdrawal`" } ], "inputFields": null, @@ -9050,92 +9216,6 @@ "enumValues": null, "possibleTypes": null }, - { - "kind": "INPUT_OBJECT", - "name": "WithdrawIncomingPaymentLiquidityInput", - "description": null, - "fields": null, - "inputFields": [ - { - "name": "idempotencyKey", - "description": "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "incomingPaymentId", - "description": "The id of the incoming payment to withdraw from.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, - { - "kind": "INPUT_OBJECT", - "name": "WithdrawOutgoingPaymentLiquidityInput", - "description": null, - "fields": null, - "inputFields": [ - { - "name": "idempotencyKey", - "description": "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - }, - { - "name": "outgoingPaymentId", - "description": "The id of the outgoing payment to withdraw from.", - "type": { - "kind": "NON_NULL", - "name": null, - "ofType": { - "kind": "SCALAR", - "name": "String", - "ofType": null - } - }, - "defaultValue": null, - "isDeprecated": false, - "deprecationReason": null - } - ], - "interfaces": null, - "enumValues": null, - "possibleTypes": null - }, { "kind": "OBJECT", "name": "__Directive", diff --git a/packages/backend/src/graphql/generated/graphql.ts b/packages/backend/src/graphql/generated/graphql.ts index 61ebb6868b..0de5e4b8f0 100644 --- a/packages/backend/src/graphql/generated/graphql.ts +++ b/packages/backend/src/graphql/generated/graphql.ts @@ -130,6 +130,8 @@ export type CreateAssetLiquidityWithdrawalInput = { id: Scalars['String']['input']; /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; }; export type CreateIncomingPaymentInput = { @@ -145,6 +147,15 @@ export type CreateIncomingPaymentInput = { walletAddressId: Scalars['String']['input']; }; +export type CreateIncomingPaymentWithdrawalInput = { + /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ + idempotencyKey: Scalars['String']['input']; + /** The id of the incoming payment to withdraw from. */ + incomingPaymentId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; +}; + export type CreateOrUpdatePeerByUrlInput = { /** Asset id of peering relationship */ assetId: Scalars['String']['input']; @@ -194,6 +205,15 @@ export type CreateOutgoingPaymentInput = { walletAddressId: Scalars['String']['input']; }; +export type CreateOutgoingPaymentWithdrawalInput = { + /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ + idempotencyKey: Scalars['String']['input']; + /** The id of the outgoing payment to withdraw from. */ + outgoingPaymentId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; +}; + export type CreatePeerInput = { /** Asset id of peering relationship */ assetId: Scalars['String']['input']; @@ -222,6 +242,8 @@ export type CreatePeerLiquidityWithdrawalInput = { idempotencyKey: Scalars['String']['input']; /** The id of the peer to create the withdrawal for. */ peerId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; }; export type CreatePeerMutationResponse = MutationResponse & { @@ -306,6 +328,8 @@ export type CreateWalletAddressWithdrawalInput = { id: Scalars['String']['input']; /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; /** The id of the Open Payments wallet address to create the withdrawal for. */ walletAddressId: Scalars['String']['input']; }; @@ -566,12 +590,16 @@ export type Mutation = { createAssetLiquidityWithdrawal?: Maybe; /** Create an internal Open Payments Incoming Payment. The receiver has a wallet address on this Rafiki instance. */ createIncomingPayment: IncomingPaymentResponse; + /** Withdraw incoming payment liquidity */ + createIncomingPaymentWithdrawal?: Maybe; /** Create a peer using a URL */ createOrUpdatePeerByUrl: CreateOrUpdatePeerByUrlMutationResponse; /** Create an Open Payments Outgoing Payment */ createOutgoingPayment: OutgoingPaymentResponse; /** Create an Open Payments Outgoing Payment from an incoming payment */ createOutgoingPaymentFromIncomingPayment: OutgoingPaymentResponse; + /** Withdraw outgoing payment liquidity */ + createOutgoingPaymentWithdrawal?: Maybe; /** Create a peer */ createPeer: CreatePeerMutationResponse; /** Withdraw peer liquidity */ @@ -617,13 +645,9 @@ export type Mutation = { voidLiquidityWithdrawal?: Maybe; /** * Withdraw webhook event liquidity - * @deprecated Use `withdrawOutgoingPaymentLiquidity, withdrawIncomingPaymentLiquidity, or createWalletAddressWithdrawal` + * @deprecated Use `createOutgoingPaymentWithdrawal, createIncomingPaymentWithdrawal, or createWalletAddressWithdrawal` */ withdrawEventLiquidity?: Maybe; - /** Withdraw incoming payment liquidity */ - withdrawIncomingPaymentLiquidity?: Maybe; - /** Withdraw outgoing payment liquidity */ - withdrawOutgoingPaymentLiquidity?: Maybe; }; @@ -647,6 +671,11 @@ export type MutationCreateIncomingPaymentArgs = { }; +export type MutationCreateIncomingPaymentWithdrawalArgs = { + input: CreateIncomingPaymentWithdrawalInput; +}; + + export type MutationCreateOrUpdatePeerByUrlArgs = { input: CreateOrUpdatePeerByUrlInput; }; @@ -662,6 +691,11 @@ export type MutationCreateOutgoingPaymentFromIncomingPaymentArgs = { }; +export type MutationCreateOutgoingPaymentWithdrawalArgs = { + input: CreateOutgoingPaymentWithdrawalInput; +}; + + export type MutationCreatePeerArgs = { input: CreatePeerInput; }; @@ -766,16 +800,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; - -export type MutationWithdrawIncomingPaymentLiquidityArgs = { - input: WithdrawIncomingPaymentLiquidityInput; -}; - - -export type MutationWithdrawOutgoingPaymentLiquidityArgs = { - input: WithdrawOutgoingPaymentLiquidityInput; -}; - export type MutationResponse = { code: Scalars['String']['output']; message: Scalars['String']['output']; @@ -1404,20 +1428,6 @@ export type WithdrawEventLiquidityInput = { idempotencyKey: Scalars['String']['input']; }; -export type WithdrawIncomingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the incoming payment to withdraw from. */ - incomingPaymentId: Scalars['String']['input']; -}; - -export type WithdrawOutgoingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the outgoing payment to withdraw from. */ - outgoingPaymentId: Scalars['String']['input']; -}; - export type ResolverTypeWrapper = Promise | T; @@ -1508,10 +1518,12 @@ export type ResolversTypes = { CreateAssetInput: ResolverTypeWrapper>; CreateAssetLiquidityWithdrawalInput: ResolverTypeWrapper>; CreateIncomingPaymentInput: ResolverTypeWrapper>; + CreateIncomingPaymentWithdrawalInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlMutationResponse: ResolverTypeWrapper>; CreateOutgoingPaymentFromIncomingPaymentInput: ResolverTypeWrapper>; CreateOutgoingPaymentInput: ResolverTypeWrapper>; + CreateOutgoingPaymentWithdrawalInput: ResolverTypeWrapper>; CreatePeerInput: ResolverTypeWrapper>; CreatePeerLiquidityWithdrawalInput: ResolverTypeWrapper>; CreatePeerMutationResponse: ResolverTypeWrapper>; @@ -1610,8 +1622,6 @@ export type ResolversTypes = { WebhookEventsConnection: ResolverTypeWrapper>; WebhookEventsEdge: ResolverTypeWrapper>; WithdrawEventLiquidityInput: ResolverTypeWrapper>; - WithdrawIncomingPaymentLiquidityInput: ResolverTypeWrapper>; - WithdrawOutgoingPaymentLiquidityInput: ResolverTypeWrapper>; }; /** Mapping between all available schema types and the resolvers parents */ @@ -1628,10 +1638,12 @@ export type ResolversParentTypes = { CreateAssetInput: Partial; CreateAssetLiquidityWithdrawalInput: Partial; CreateIncomingPaymentInput: Partial; + CreateIncomingPaymentWithdrawalInput: Partial; CreateOrUpdatePeerByUrlInput: Partial; CreateOrUpdatePeerByUrlMutationResponse: Partial; CreateOutgoingPaymentFromIncomingPaymentInput: Partial; CreateOutgoingPaymentInput: Partial; + CreateOutgoingPaymentWithdrawalInput: Partial; CreatePeerInput: Partial; CreatePeerLiquidityWithdrawalInput: Partial; CreatePeerMutationResponse: Partial; @@ -1721,8 +1733,6 @@ export type ResolversParentTypes = { WebhookEventsConnection: Partial; WebhookEventsEdge: Partial; WithdrawEventLiquidityInput: Partial; - WithdrawIncomingPaymentLiquidityInput: Partial; - WithdrawOutgoingPaymentLiquidityInput: Partial; }; export type AmountResolvers = { @@ -1921,9 +1931,11 @@ export type MutationResolvers>; createAssetLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createIncomingPayment?: Resolver>; + createIncomingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createOrUpdatePeerByUrl?: Resolver>; createOutgoingPayment?: Resolver>; createOutgoingPaymentFromIncomingPayment?: Resolver>; + createOutgoingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createPeer?: Resolver>; createPeerLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createQuote?: Resolver>; @@ -1945,8 +1957,6 @@ export type MutationResolvers>; voidLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; withdrawEventLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawIncomingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawOutgoingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; }; export type MutationResponseResolvers = { diff --git a/packages/backend/src/graphql/resolvers/index.ts b/packages/backend/src/graphql/resolvers/index.ts index 9696a2a8ad..0f7321b119 100644 --- a/packages/backend/src/graphql/resolvers/index.ts +++ b/packages/backend/src/graphql/resolvers/index.ts @@ -46,8 +46,8 @@ import { depositEventLiquidity, withdrawEventLiquidity, depositOutgoingPaymentLiquidity, - withdrawIncomingPaymentLiquidity, - withdrawOutgoingPaymentLiquidity + createIncomingPaymentWithdrawal, + createOutgoingPaymentWithdrawal } from './liquidity' import { GraphQLBigInt, GraphQLUInt8 } from '../scalars' import { @@ -133,8 +133,8 @@ export const resolvers: Resolvers = { depositEventLiquidity, withdrawEventLiquidity, depositOutgoingPaymentLiquidity, - withdrawIncomingPaymentLiquidity, - withdrawOutgoingPaymentLiquidity, + createIncomingPaymentWithdrawal, + createOutgoingPaymentWithdrawal, setFee } } diff --git a/packages/backend/src/graphql/resolvers/liquidity.test.ts b/packages/backend/src/graphql/resolvers/liquidity.test.ts index 132929524f..48ba6c2fde 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.test.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.test.ts @@ -50,7 +50,7 @@ describe('Liquidity Resolvers', (): void => { let appContainer: TestContainer let accountingService: AccountingService let knex: Knex - const timeout = 10 + const timeoutTwoPhase = 10 beforeAll(async (): Promise => { deps = await initIocContainer(Config) @@ -500,7 +500,8 @@ describe('Liquidity Resolvers', (): void => { id: uuid(), peerId: peer.id, amount: startingBalance.toString(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -537,7 +538,8 @@ describe('Liquidity Resolvers', (): void => { id: uuid(), peerId: uuid(), amount: '100', - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -575,7 +577,8 @@ describe('Liquidity Resolvers', (): void => { id: 'not a uuid', peerId: peer.id, amount: startingBalance.toString(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -621,7 +624,8 @@ describe('Liquidity Resolvers', (): void => { id, peerId: peer.id, amount: startingBalance.toString(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -664,7 +668,8 @@ describe('Liquidity Resolvers', (): void => { id: uuid(), peerId: peer.id, amount: amount.toString(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -719,7 +724,8 @@ describe('Liquidity Resolvers', (): void => { id: uuid(), assetId: asset.id, amount: startingBalance.toString(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -756,7 +762,8 @@ describe('Liquidity Resolvers', (): void => { id: uuid(), assetId: uuid(), amount: '100', - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -794,7 +801,8 @@ describe('Liquidity Resolvers', (): void => { id: 'not a uuid', assetId: asset.id, amount: startingBalance.toString(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -840,7 +848,8 @@ describe('Liquidity Resolvers', (): void => { id, assetId: asset.id, amount: startingBalance.toString(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -883,7 +892,8 @@ describe('Liquidity Resolvers', (): void => { id: uuid(), assetId: asset.id, amount: amount.toString(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -948,7 +958,8 @@ describe('Liquidity Resolvers', (): void => { input: { id, walletAddressId: walletAddress.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -994,7 +1005,8 @@ describe('Liquidity Resolvers', (): void => { input: { id: uuid(), walletAddressId: uuid(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -1035,7 +1047,8 @@ describe('Liquidity Resolvers', (): void => { input: { id: 'not a uuid', walletAddressId: walletAddress.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -1084,7 +1097,8 @@ describe('Liquidity Resolvers', (): void => { input: { id, walletAddressId: walletAddress.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -1108,7 +1122,7 @@ describe('Liquidity Resolvers', (): void => { id: uuid(), account: walletAddress, amount, - timeout + timeout: 0 }) ).resolves.toBeUndefined() const response = await appContainer.apolloClient @@ -1132,7 +1146,8 @@ describe('Liquidity Resolvers', (): void => { input: { id: uuid(), walletAddressId: walletAddress.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) @@ -1172,7 +1187,7 @@ describe('Liquidity Resolvers', (): void => { ...deposit, id: withdrawalId, amount: BigInt(10), - timeout + timeout: timeoutTwoPhase }) ).resolves.toBeUndefined() }) @@ -1385,7 +1400,7 @@ describe('Liquidity Resolvers', (): void => { ...deposit, id: withdrawalId, amount: BigInt(10), - timeout + timeout: timeoutTwoPhase }) ).resolves.toBeUndefined() }) @@ -2007,7 +2022,7 @@ describe('Liquidity Resolvers', (): void => { ).resolves.toEqual(BigInt(0)) }) - describe('withdrawIncomingPaymentLiquidity', (): void => { + describe('createIncomingPaymentWithdrawal', (): void => { const amount = BigInt(10) beforeEach(async (): Promise => { @@ -2046,10 +2061,10 @@ describe('Liquidity Resolvers', (): void => { const response = await appContainer.apolloClient .mutate({ mutation: gql` - mutation WithdrawIncomingPaymentLiquidity( - $input: WithdrawIncomingPaymentLiquidityInput! + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! ) { - withdrawIncomingPaymentLiquidity(input: $input) { + createIncomingPaymentWithdrawal(input: $input) { code success message @@ -2060,13 +2075,14 @@ describe('Liquidity Resolvers', (): void => { variables: { input: { incomingPaymentId: incomingPayment.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawIncomingPaymentLiquidity + return query.data.createIncomingPaymentWithdrawal } else { throw new Error('Data was empty') } @@ -2097,10 +2113,10 @@ describe('Liquidity Resolvers', (): void => { const response = await appContainer.apolloClient .mutate({ mutation: gql` - mutation WithdrawIncomingPaymentLiquidity( - $input: WithdrawIncomingPaymentLiquidityInput! + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! ) { - withdrawIncomingPaymentLiquidity(input: $input) { + createIncomingPaymentWithdrawal(input: $input) { code success message @@ -2111,13 +2127,14 @@ describe('Liquidity Resolvers', (): void => { variables: { input: { incomingPaymentId: uuid(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawIncomingPaymentLiquidity + return query.data.createIncomingPaymentWithdrawal } else { throw new Error('Data was empty') } @@ -2133,10 +2150,10 @@ describe('Liquidity Resolvers', (): void => { const response = await appContainer.apolloClient .mutate({ mutation: gql` - mutation WithdrawIncomingPaymentLiquidity( - $input: WithdrawIncomingPaymentLiquidityInput! + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! ) { - withdrawIncomingPaymentLiquidity(input: $input) { + createIncomingPaymentWithdrawal(input: $input) { code success message @@ -2147,13 +2164,14 @@ describe('Liquidity Resolvers', (): void => { variables: { input: { incomingPaymentId: incomingPayment.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawIncomingPaymentLiquidity + return query.data.createIncomingPaymentWithdrawal } else { throw new Error('Data was empty') } @@ -2188,10 +2206,10 @@ describe('Liquidity Resolvers', (): void => { const response = await appContainer.apolloClient .mutate({ mutation: gql` - mutation WithdrawIncomingPaymentLiquidity( - $input: WithdrawIncomingPaymentLiquidityInput! + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! ) { - withdrawIncomingPaymentLiquidity(input: $input) { + createIncomingPaymentWithdrawal(input: $input) { code success message @@ -2202,13 +2220,14 @@ describe('Liquidity Resolvers', (): void => { variables: { input: { incomingPaymentId: incomingPayment.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawIncomingPaymentLiquidity + return query.data.createIncomingPaymentWithdrawal } else { throw new Error('Data was empty') } @@ -2222,7 +2241,7 @@ describe('Liquidity Resolvers', (): void => { }) }) - describe('withdrawOutgoingPaymentLiquidity', (): void => { + describe('createOutgoingPaymentWithdrawal', (): void => { const amount = BigInt(10) beforeEach(async (): Promise => { @@ -2261,10 +2280,10 @@ describe('Liquidity Resolvers', (): void => { const response = await appContainer.apolloClient .mutate({ mutation: gql` - mutation WithdrawOutgoingPaymentLiquidity( - $input: WithdrawOutgoingPaymentLiquidityInput! + mutation CreateOutgoingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! ) { - withdrawOutgoingPaymentLiquidity(input: $input) { + createOutgoingPaymentWithdrawal(input: $input) { code success message @@ -2275,13 +2294,14 @@ describe('Liquidity Resolvers', (): void => { variables: { input: { outgoingPaymentId: outgoingPayment.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawOutgoingPaymentLiquidity + return query.data.createOutgoingPaymentWithdrawal } else { throw new Error('Data was empty') } @@ -2301,10 +2321,10 @@ describe('Liquidity Resolvers', (): void => { const response = await appContainer.apolloClient .mutate({ mutation: gql` - mutation WithdrawOutgoingPaymentLiquidity( - $input: WithdrawOutgoingPaymentLiquidityInput! + mutation CreateOutgoingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! ) { - withdrawOutgoingPaymentLiquidity(input: $input) { + createOutgoingPaymentWithdrawal(input: $input) { code success message @@ -2315,13 +2335,14 @@ describe('Liquidity Resolvers', (): void => { variables: { input: { outgoingPaymentId: uuid(), - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawOutgoingPaymentLiquidity + return query.data.createOutgoingPaymentWithdrawal } else { throw new Error('Data was empty') } @@ -2343,10 +2364,10 @@ describe('Liquidity Resolvers', (): void => { const response = await appContainer.apolloClient .mutate({ mutation: gql` - mutation withdrawOutgoingPaymentLiquidity( - $input: WithdrawOutgoingPaymentLiquidityInput! + mutation CreateIncomingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! ) { - withdrawOutgoingPaymentLiquidity(input: $input) { + createOutgoingPaymentWithdrawal(input: $input) { code success message @@ -2357,13 +2378,14 @@ describe('Liquidity Resolvers', (): void => { variables: { input: { outgoingPaymentId: outgoingPayment.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawOutgoingPaymentLiquidity + return query.data.createOutgoingPaymentWithdrawal } else { throw new Error('Data was empty') } @@ -2396,10 +2418,10 @@ describe('Liquidity Resolvers', (): void => { const response = await appContainer.apolloClient .mutate({ mutation: gql` - mutation withdrawOutgoingPaymentLiquidity( - $input: WithdrawOutgoingPaymentLiquidityInput! + mutation CreateOutgoingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! ) { - withdrawOutgoingPaymentLiquidity(input: $input) { + createOutgoingPaymentWithdrawal(input: $input) { code success message @@ -2410,13 +2432,14 @@ describe('Liquidity Resolvers', (): void => { variables: { input: { outgoingPaymentId: outgoingPayment.id, - idempotencyKey: uuid() + idempotencyKey: uuid(), + timeoutSeconds: 0 } } }) .then((query): LiquidityMutationResponse => { if (query.data) { - return query.data.withdrawOutgoingPaymentLiquidity + return query.data.createOutgoingPaymentWithdrawal } else { throw new Error('Data was empty') } diff --git a/packages/backend/src/graphql/resolvers/liquidity.ts b/packages/backend/src/graphql/resolvers/liquidity.ts index 0659ad78c1..df2e6d59fe 100644 --- a/packages/backend/src/graphql/resolvers/liquidity.ts +++ b/packages/backend/src/graphql/resolvers/liquidity.ts @@ -170,20 +170,21 @@ export const createPeerLiquidityWithdrawal: MutationResolvers['cr ctx ): Promise => { try { - if (args.input.amount === BigInt(0)) { + const { amount, id, timeoutSeconds, peerId } = args.input + if (amount === BigInt(0)) { return responses[LiquidityError.AmountZero] } const peerService = await ctx.container.use('peerService') - const peer = await peerService.get(args.input.peerId) + const peer = await peerService.get(peerId) if (!peer) { return responses[LiquidityError.UnknownPeer] } const accountingService = await ctx.container.use('accountingService') const error = await accountingService.createWithdrawal({ - id: args.input.id, + id, account: peer, - amount: args.input.amount, - timeout: 60 + amount, + timeout: Number(timeoutSeconds) }) if (error) { return errorToResponse(error) @@ -216,20 +217,21 @@ export const createAssetLiquidityWithdrawal: MutationResolvers['c ctx ): Promise => { try { - if (args.input.amount === BigInt(0)) { + const { amount, id, timeoutSeconds, assetId } = args.input + if (amount === 0n) { return responses[LiquidityError.AmountZero] } const assetService = await ctx.container.use('assetService') - const asset = await assetService.get(args.input.assetId) + const asset = await assetService.get(assetId) if (!asset) { return responses[LiquidityError.UnknownAsset] } const accountingService = await ctx.container.use('accountingService') const error = await accountingService.createWithdrawal({ - id: args.input.id, + id, account: asset, - amount: args.input.amount, - timeout: 60 + amount, + timeout: Number(timeoutSeconds) }) if (error) { return errorToResponse(error) @@ -262,23 +264,23 @@ export const createWalletAddressWithdrawal: MutationResolvers['cr ctx ): Promise => { try { + const { id, walletAddressId, timeoutSeconds } = args.input const walletAddressService = await ctx.container.use( 'walletAddressService' ) - const walletAddress = await walletAddressService.get( - args.input.walletAddressId - ) + const walletAddress = await walletAddressService.get(walletAddressId) if (!walletAddress) { return responses[ LiquidityError.UnknownWalletAddress ] as unknown as WalletAddressWithdrawalMutationResponse } - const id = args.input.id const accountingService = await ctx.container.use('accountingService') const amount = await accountingService.getBalance(walletAddress.id) if (amount === undefined) - throw new Error('missing incoming payment wallet address') - if (amount === BigInt(0)) { + throw new Error( + `Could not get balance for wallet address liquidity account. It's likely the liquidity account does not exist.` + ) + else if (amount === 0n) { return responses[ LiquidityError.AmountZero ] as unknown as WalletAddressWithdrawalMutationResponse @@ -287,7 +289,7 @@ export const createWalletAddressWithdrawal: MutationResolvers['cr id, account: walletAddress, amount, - timeout: 60 + timeout: Number(timeoutSeconds) }) if (error) { @@ -522,13 +524,13 @@ export const depositOutgoingPaymentLiquidity: MutationResolvers[' } } -export const withdrawIncomingPaymentLiquidity: MutationResolvers['withdrawIncomingPaymentLiquidity'] = +export const createIncomingPaymentWithdrawal: MutationResolvers['createIncomingPaymentWithdrawal'] = async ( parent, args, ctx ): Promise => { - const { incomingPaymentId } = args.input + const { incomingPaymentId, timeoutSeconds } = args.input try { const incomingPaymentService = await ctx.container.use( 'incomingPaymentService' @@ -555,7 +557,8 @@ export const withdrawIncomingPaymentLiquidity: MutationResolvers[ id: incomingPaymentId, asset: incomingPayment.asset }, - amount: incomingPayment.receivedAmount.value + amount: incomingPayment.receivedAmount.value, + timeout: Number(timeoutSeconds) }) if (error) { @@ -582,13 +585,13 @@ export const withdrawIncomingPaymentLiquidity: MutationResolvers[ } } -export const withdrawOutgoingPaymentLiquidity: MutationResolvers['withdrawOutgoingPaymentLiquidity'] = +export const createOutgoingPaymentWithdrawal: MutationResolvers['createOutgoingPaymentWithdrawal'] = async ( parent, args, ctx ): Promise => { - const { outgoingPaymentId } = args.input + const { outgoingPaymentId, timeoutSeconds } = args.input try { const outgoingPaymentService = await ctx.container.use( 'outgoingPaymentService' @@ -620,7 +623,8 @@ export const withdrawOutgoingPaymentLiquidity: MutationResolvers[ id: outgoingPaymentId, asset: outgoingPayment.asset }, - amount: balance + amount: balance, + timeout: Number(timeoutSeconds) }) if (error) { diff --git a/packages/backend/src/graphql/schema.graphql b/packages/backend/src/graphql/schema.graphql index 858ed7e95c..7428be7afa 100644 --- a/packages/backend/src/graphql/schema.graphql +++ b/packages/backend/src/graphql/schema.graphql @@ -203,17 +203,17 @@ type Mutation { input: WithdrawEventLiquidityInput! ): LiquidityMutationResponse @deprecated( - reason: "Use `withdrawOutgoingPaymentLiquidity, withdrawIncomingPaymentLiquidity, or createWalletAddressWithdrawal`" + reason: "Use `createOutgoingPaymentWithdrawal, createIncomingPaymentWithdrawal, or createWalletAddressWithdrawal`" ) "Withdraw incoming payment liquidity" - withdrawIncomingPaymentLiquidity( - input: WithdrawIncomingPaymentLiquidityInput! + createIncomingPaymentWithdrawal( + input: CreateIncomingPaymentWithdrawalInput! ): LiquidityMutationResponse "Withdraw outgoing payment liquidity" - withdrawOutgoingPaymentLiquidity( - input: WithdrawOutgoingPaymentLiquidityInput! + createOutgoingPaymentWithdrawal( + input: CreateOutgoingPaymentWithdrawalInput! ): LiquidityMutationResponse "Deposit outgoing payment liquidity" @@ -393,6 +393,8 @@ input CreatePeerLiquidityWithdrawalInput { id: String! "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)" idempotencyKey: String! + "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer." + timeoutSeconds: UInt64! } input CreateAssetLiquidityWithdrawalInput { @@ -404,6 +406,8 @@ input CreateAssetLiquidityWithdrawalInput { id: String! "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)" idempotencyKey: String! + "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer." + timeoutSeconds: UInt64! } input PostLiquidityWithdrawalInput { @@ -427,18 +431,22 @@ input DepositOutgoingPaymentLiquidityInput { idempotencyKey: String! } -input WithdrawIncomingPaymentLiquidityInput { +input CreateIncomingPaymentWithdrawalInput { "The id of the incoming payment to withdraw from." incomingPaymentId: String! "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)" idempotencyKey: String! + "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer." + timeoutSeconds: UInt64! } -input WithdrawOutgoingPaymentLiquidityInput { +input CreateOutgoingPaymentWithdrawalInput { "The id of the outgoing payment to withdraw from." outgoingPaymentId: String! "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)" idempotencyKey: String! + "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer." + timeoutSeconds: UInt64! } input DepositEventLiquidityInput { @@ -462,6 +470,8 @@ input CreateWalletAddressWithdrawalInput { id: String! "Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence)" idempotencyKey: String! + "This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer." + timeoutSeconds: UInt64! } input JwkInput { diff --git a/packages/documentation/README.md b/packages/documentation/README.md index 51292c04f5..824def64ee 100644 --- a/packages/documentation/README.md +++ b/packages/documentation/README.md @@ -14,7 +14,7 @@ This website is built with [Starlight](https://starlight.astro.build/), a docume $ pnpm i ``` -- Run the dev server from the /packages/documentation folder: +- Run the dev server from the `/packages/documentation` folder: ```sh $ pnpm start @@ -22,7 +22,7 @@ $ pnpm start This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server. -- Build the site, again, this must be run from the /packages/documentation folder: +- Build the site, again, this must be run from the `/packages/documentation` folder: ```sh $ pnpm build:docs diff --git a/packages/documentation/src/content/docs/concepts/accounting/liquidity.md b/packages/documentation/src/content/docs/concepts/accounting/liquidity.md index 8471b69480..06a603a34a 100644 --- a/packages/documentation/src/content/docs/concepts/accounting/liquidity.md +++ b/packages/documentation/src/content/docs/concepts/accounting/liquidity.md @@ -89,11 +89,14 @@ where "id": "b97fd85a-126e-42ef-b40d-1a50a70ffa6f", "assetId": "7b8b0f65-896d-4403-b7ba-2e24bf20eb35", "amount": "100", - "idempotencyKey": "b97fd85a-126e-42ef-b40d-1a50a70ffa6f" + "idempotencyKey": "b97fd85a-126e-42ef-b40d-1a50a70ffa6f", + "timeoutSeconds": 0 } } ``` +See `PostLiquidityWithdrawal` and `VoidLiquidityWithdrawal` at the [below](#postliquiditywithdrawal-or-voidliquiditywithdrawal) section. + ### Peer Liquidity Deposit and withdraw peer liquidity via the Admin API (or UI): @@ -117,7 +120,8 @@ where "id": "a09b730d-8610-4fda-98fa-ec7acb19c775", "peerId": "73158598-2e0c-4973-895e-aebd115af260", "amount": "1000000", - "idempotencyKey": "a09b730d-8610-4fda-98fa-ec7acb19c775" + "idempotencyKey": "a09b730d-8610-4fda-98fa-ec7acb19c775", + "timeoutSeconds": 0 } } ``` @@ -144,11 +148,14 @@ where "input": { "id": "421fae87-9a59-4217-9ff8-faf55ffab9c6", "peerId": "73158598-2e0c-4973-895e-aebd115af260", - "amount": "100" + "amount": "100", + "timeoutSeconds": 0 } } ``` +See `PostLiquidityWithdrawal` and `VoidLiquidityWithdrawal` at the [below](#postliquiditywithdrawal-or-voidliquiditywithdrawal) section. + ### Payment Liquidity #### Outgoing payment @@ -182,10 +189,10 @@ where and ```graphql -mutation WithdrawOutgoingPaymentLiquidity( - $input: WithdrawOutgoingPaymentLiquidityInput! +mutation CreateOutgoingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! ) { - withdrawOutgoingPaymentLiquidity(input: $input) { + createOutgoingPaymentWithdrawal(input: $input) { code error message @@ -200,20 +207,23 @@ where { "input": { "outgoingPaymentId": "b4f85d5c-652d-472d-873c-4ba2a5e39052", - "idempotencyKey": "a09b730d-8610-4fda-98fa-ec7acb19c775" + "idempotencyKey": "a09b730d-8610-4fda-98fa-ec7acb19c775", + "timeoutSeconds": 0 } } ``` +See `PostLiquidityWithdrawal` and `VoidLiquidityWithdrawal` at the [below](#postliquiditywithdrawal-or-voidliquiditywithdrawal) section. + #### Incoming payment Withdraw incoming payment liquidity via the Admin API only: ```graphql -mutation WithdrawIncomingPaymentLiquidity( - $input: WithdrawIncomingPaymentLiquidityInput! +mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! ) { - withdrawIncomingPaymentLiquidity(input: $input) { + createIncomingPaymentWithdrawal(input: $input) { code error message @@ -228,6 +238,78 @@ where { "input": { "incomingPaymentId": "b4f85d5c-652d-472d-873c-4ba2a5e39052", + "idempotencyKey": "a09b730d-8610-4fda-98fa-ec7acb19c775", + "timeoutSeconds": 0 + } +} +``` + +See `PostLiquidityWithdrawal` and `VoidLiquidityWithdrawal` at the [below](#postliquiditywithdrawal-or-voidliquiditywithdrawal) section. + +## `PostLiquidityWithdrawal` or `VoidLiquidityWithdrawal` + +`PostLiquidityWithdrawal` and `VoidLiquidityWithdrawal` are only applicable for two-phase withdrawals. + +- `PostLiquidityWithdrawal` - Post liquidity withdrawal. Withdrawals with `> 0` timeouts are two-phase transfers and are committed via this mutation. +- `VoidLiquidityWithdrawal` - Void liquidity withdrawal. Withdrawals with `> 0` timeouts are two-phase transfers and are rolled back via this mutation. + +When a withdrawal liquidity transaction is requested with a non-zero `timeout` value _(Zero denotes absence of timeout)_, +the transfer will be created as a two-phase transfer [see more](https://en.wikipedia.org/wiki/Two-phase_commit_protocol) + +If the timeout interval passes before the transfer is either posted or voided, the transfer expires and the full amount is returned to the original account. +Note that timeouts are given as intervals, specified in seconds, rather than as absolute timestamps. + +The following withdrawal payments support two-phase transfers: + +- Asset Liquidity Withdrawal +- Wallet Address Withdrawal +- Peer Liquidity Withdrawal +- Incoming Payment Withdrawal +- Outgoing Payment Withdrawal + +### PostLiquidityWithdrawal + +```graphql +mutation PostLiquidityWithdrawal($input: PostLiquidityWithdrawalInput!) { + postLiquidityWithdrawal(input: $input) { + code + error + message + success + } +} +``` + +where + +```json +{ + "input": { + "withdrawalId": "b4f85d5c-652d-472d-873c-4ba2a5e39052", + "idempotencyKey": "a09b730d-8610-4fda-98fa-ec7acb19c775" + } +} +``` + +### VoidLiquidityWithdrawal + +```graphql +mutation VoidLiquidityWithdrawal($input: VoidLiquidityWithdrawalInput!) { + voidLiquidityWithdrawal(input: $input) { + code + error + message + success + } +} +``` + +where + +```json +{ + "input": { + "withdrawalId": "b4f85d5c-652d-472d-873c-4ba2a5e39052", "idempotencyKey": "a09b730d-8610-4fda-98fa-ec7acb19c775" } } diff --git a/packages/documentation/src/content/docs/concepts/accounting/tigerbeetle.md b/packages/documentation/src/content/docs/concepts/accounting/tigerbeetle.md index 4b7c97a616..84ce2fde05 100644 --- a/packages/documentation/src/content/docs/concepts/accounting/tigerbeetle.md +++ b/packages/documentation/src/content/docs/concepts/accounting/tigerbeetle.md @@ -15,7 +15,7 @@ Rafiki uses a combination of liquidity and settlement accounts to perform double pnpm --filter backend up tigerbeetle-node --latest # specific version -pnpm --filter backend up tigerbeetle-node@0.12.24 +pnpm --filter backend up tigerbeetle-node@0.15.3 ``` ### Production Environment - Helm charts diff --git a/packages/documentation/src/content/docs/integration/event-handlers.mdx b/packages/documentation/src/content/docs/integration/event-handlers.mdx index 7b72d5af9c..8d9a4d44a2 100644 --- a/packages/documentation/src/content/docs/integration/event-handlers.mdx +++ b/packages/documentation/src/content/docs/integration/event-handlers.mdx @@ -25,7 +25,9 @@ The `incoming_payment.created` event indicates that an incoming payment has been The `incoming_payment.completed` event indicates that an incoming payment has been completed, either automatically or manually, and that any funds that have been received into this incoming payment should be withdrawn and credited to the recipient's account with the Account Servicing Entity. -Example: An incoming payment was completed and received $10. +In addition, the `CreateIncomingPaymentWithdrawal` supports two-phase transfers [see more](/reference/glossary#two-phase-transfers). + +Example: An incoming payment was completed and received **$10**. >ASE: webhook event: incoming payment completed,
receivedAmount: $10 - ASE->>R: admin API call: WithdrawIncomingPaymentLiquidity + ASE->>R: admin API call: CreateIncomingPaymentWithdrawal ASE->>ASE: credit receiver's account with $10 `} /> +Example: An incoming payment supporting two-phase transfers was completed and recieved **$10**. + +>ASE: webhook event: incoming payment completed,
receivedAmount: $10 + ASE->>R: admin API call: CreateIncomingPaymentWithdrawal + ASE->>ASE: credit receiver's account with $10 + ASE->>R: admin API call: PostLiquidityWithdrawal + R->>R: 2-phase transfer completed + +`} +/> + ## `incoming_payment.expired` The `incoming_payment.expired` event indicates that an incoming payment has expired, and that any funds that have been received into this incoming payment should be withdrawn and credited to the recipient's account with the Account Servicing Entity. Note that this event is not fired if there were no funds received by the incoming payment since there is no action required by the Account Servicing Entity. -Example: An incoming payment has expired and received $2.55. +Example: An incoming payment has expired and received **$2.55**. >ASE: webhook event: incoming payment expired,
receivedAmount: $2.55 - ASE->>R: admin API call: WithdrawIncomingPaymentLiquidity + ASE->>R: admin API call: CreateIncomingPaymentWithdrawal ASE->>ASE: credit receiver's account with $2.55 `} @@ -63,7 +81,7 @@ The `outgoing_payment.created` event indicates that an outgoing payment has been In case that outgoing payment should not be fullfilled, the Account Servicing Entity can cancel outgoing payment. Otherwise, the Account Servicing Entity should put a hold on the sender’s account and deposit the funds into Rafiki. -Example: An outgoing payment for $12 has been created. +Example: An outgoing payment for **$12** has been created. >ASE: webhook event: outgoing completed,
debitAmount: $12, sentAmount:$11.50 - ASE->>R: admin API call: WithdrawOutgoingPaymentLiquidity + ASE->>R: admin API call: CreateOutgoingPaymentWithdrawal ASE->>ASE: remove the hold and deduct $12 from the sender's account,
credit ASE's account with $0.50 `} /> +Example: An outgoing payment supporting two-phase transfers for **$12** has been completed. **$11.50** were sent. The Account Servicing Entity keeps **$0.50** as fees. + +>ASE: webhook event: outgoing completed,
debitAmount: $12, sentAmount:$11.50 + ASE->>R: admin API call: CreateOutgoingPaymentWithdrawal + ASE->>ASE: remove the hold and deduct $12 from the sender's account,
credit ASE's account with $0.50 + ASE->>R: admin API call: PostLiquidityWithdrawal + R->>R: 2-phase transfer completed + +`} +/> + ## `outgoing_payment.failed` The `outgoing_payment.failed` event indicates that an outgoing payment has either partially or completely failed and a retry was also unsuccessful. The Account Servicing Entity should withdraw any remaining liquidity from that outgoing payment in Rafiki. If the payment failed completely (the `sentAmount` was 0), the Account Servicing Entity should remove the hold from the sender's account. If the payment failed partially, the Account Servicing Entity should remove the hold from the sender's account and debit it with the amount that has been sent, but they should refrain from taking a sending fee. -Example: An outgoing payment for $12 has failed. $8 were sent. +Example: An outgoing payment for **$12** has failed. **$8** were sent. >ASE: webhook event: outgoing failed,
debitAmount: $12, sentAmount:$8 - ASE->>R: admin API call: WithdrawOutgoingPaymentLiquidity + ASE->>R: admin API call: CreateOutgoingPaymentWithdrawal ASE->>ASE: remove the hold and deduct $8 from the sender's account `} @@ -122,7 +158,7 @@ Example: An outgoing payment for $12 has failed. $8 were sent. The `wallet_address.web_monetization` event indicates that a wallet address has received web monetization payments via STREAM (raw ILP access). The Account Servicing Entity should withdraw that liquidity from the wallet address and credit the receiver's account. -Example: A wallet address received $0.33 +Example: A wallet address received **$0.33** ; /** Create an internal Open Payments Incoming Payment. The receiver has a wallet address on this Rafiki instance. */ createIncomingPayment: IncomingPaymentResponse; + /** Withdraw incoming payment liquidity */ + createIncomingPaymentWithdrawal?: Maybe; /** Create a peer using a URL */ createOrUpdatePeerByUrl: CreateOrUpdatePeerByUrlMutationResponse; /** Create an Open Payments Outgoing Payment */ createOutgoingPayment: OutgoingPaymentResponse; /** Create an Open Payments Outgoing Payment from an incoming payment */ createOutgoingPaymentFromIncomingPayment: OutgoingPaymentResponse; + /** Withdraw outgoing payment liquidity */ + createOutgoingPaymentWithdrawal?: Maybe; /** Create a peer */ createPeer: CreatePeerMutationResponse; /** Withdraw peer liquidity */ @@ -617,13 +645,9 @@ export type Mutation = { voidLiquidityWithdrawal?: Maybe; /** * Withdraw webhook event liquidity - * @deprecated Use `withdrawOutgoingPaymentLiquidity, withdrawIncomingPaymentLiquidity, or createWalletAddressWithdrawal` + * @deprecated Use `createOutgoingPaymentWithdrawal, createIncomingPaymentWithdrawal, or createWalletAddressWithdrawal` */ withdrawEventLiquidity?: Maybe; - /** Withdraw incoming payment liquidity */ - withdrawIncomingPaymentLiquidity?: Maybe; - /** Withdraw outgoing payment liquidity */ - withdrawOutgoingPaymentLiquidity?: Maybe; }; @@ -647,6 +671,11 @@ export type MutationCreateIncomingPaymentArgs = { }; +export type MutationCreateIncomingPaymentWithdrawalArgs = { + input: CreateIncomingPaymentWithdrawalInput; +}; + + export type MutationCreateOrUpdatePeerByUrlArgs = { input: CreateOrUpdatePeerByUrlInput; }; @@ -662,6 +691,11 @@ export type MutationCreateOutgoingPaymentFromIncomingPaymentArgs = { }; +export type MutationCreateOutgoingPaymentWithdrawalArgs = { + input: CreateOutgoingPaymentWithdrawalInput; +}; + + export type MutationCreatePeerArgs = { input: CreatePeerInput; }; @@ -766,16 +800,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; - -export type MutationWithdrawIncomingPaymentLiquidityArgs = { - input: WithdrawIncomingPaymentLiquidityInput; -}; - - -export type MutationWithdrawOutgoingPaymentLiquidityArgs = { - input: WithdrawOutgoingPaymentLiquidityInput; -}; - export type MutationResponse = { code: Scalars['String']['output']; message: Scalars['String']['output']; @@ -1404,20 +1428,6 @@ export type WithdrawEventLiquidityInput = { idempotencyKey: Scalars['String']['input']; }; -export type WithdrawIncomingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the incoming payment to withdraw from. */ - incomingPaymentId: Scalars['String']['input']; -}; - -export type WithdrawOutgoingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the outgoing payment to withdraw from. */ - outgoingPaymentId: Scalars['String']['input']; -}; - export type ResolverTypeWrapper = Promise | T; @@ -1508,10 +1518,12 @@ export type ResolversTypes = { CreateAssetInput: ResolverTypeWrapper>; CreateAssetLiquidityWithdrawalInput: ResolverTypeWrapper>; CreateIncomingPaymentInput: ResolverTypeWrapper>; + CreateIncomingPaymentWithdrawalInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlMutationResponse: ResolverTypeWrapper>; CreateOutgoingPaymentFromIncomingPaymentInput: ResolverTypeWrapper>; CreateOutgoingPaymentInput: ResolverTypeWrapper>; + CreateOutgoingPaymentWithdrawalInput: ResolverTypeWrapper>; CreatePeerInput: ResolverTypeWrapper>; CreatePeerLiquidityWithdrawalInput: ResolverTypeWrapper>; CreatePeerMutationResponse: ResolverTypeWrapper>; @@ -1610,8 +1622,6 @@ export type ResolversTypes = { WebhookEventsConnection: ResolverTypeWrapper>; WebhookEventsEdge: ResolverTypeWrapper>; WithdrawEventLiquidityInput: ResolverTypeWrapper>; - WithdrawIncomingPaymentLiquidityInput: ResolverTypeWrapper>; - WithdrawOutgoingPaymentLiquidityInput: ResolverTypeWrapper>; }; /** Mapping between all available schema types and the resolvers parents */ @@ -1628,10 +1638,12 @@ export type ResolversParentTypes = { CreateAssetInput: Partial; CreateAssetLiquidityWithdrawalInput: Partial; CreateIncomingPaymentInput: Partial; + CreateIncomingPaymentWithdrawalInput: Partial; CreateOrUpdatePeerByUrlInput: Partial; CreateOrUpdatePeerByUrlMutationResponse: Partial; CreateOutgoingPaymentFromIncomingPaymentInput: Partial; CreateOutgoingPaymentInput: Partial; + CreateOutgoingPaymentWithdrawalInput: Partial; CreatePeerInput: Partial; CreatePeerLiquidityWithdrawalInput: Partial; CreatePeerMutationResponse: Partial; @@ -1721,8 +1733,6 @@ export type ResolversParentTypes = { WebhookEventsConnection: Partial; WebhookEventsEdge: Partial; WithdrawEventLiquidityInput: Partial; - WithdrawIncomingPaymentLiquidityInput: Partial; - WithdrawOutgoingPaymentLiquidityInput: Partial; }; export type AmountResolvers = { @@ -1921,9 +1931,11 @@ export type MutationResolvers>; createAssetLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createIncomingPayment?: Resolver>; + createIncomingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createOrUpdatePeerByUrl?: Resolver>; createOutgoingPayment?: Resolver>; createOutgoingPaymentFromIncomingPayment?: Resolver>; + createOutgoingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createPeer?: Resolver>; createPeerLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createQuote?: Resolver>; @@ -1945,8 +1957,6 @@ export type MutationResolvers>; voidLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; withdrawEventLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawIncomingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawOutgoingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; }; export type MutationResponseResolvers = { @@ -2415,19 +2425,19 @@ export type DepositOutgoingPaymentLiquidityVariables = Exact<{ export type DepositOutgoingPaymentLiquidity = { __typename?: 'Mutation', depositOutgoingPaymentLiquidity?: { __typename?: 'LiquidityMutationResponse', success: boolean, message: string } | null }; -export type WithdrawOutgoingPaymentLiquidityVariables = Exact<{ - input: WithdrawOutgoingPaymentLiquidityInput; +export type CreateOutgoingPaymentWithdrawalVariables = Exact<{ + input: CreateOutgoingPaymentWithdrawalInput; }>; -export type WithdrawOutgoingPaymentLiquidity = { __typename?: 'Mutation', withdrawOutgoingPaymentLiquidity?: { __typename?: 'LiquidityMutationResponse', success: boolean, message: string } | null }; +export type CreateOutgoingPaymentWithdrawal = { __typename?: 'Mutation', createOutgoingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', success: boolean, message: string } | null }; -export type WithdrawIncomingPaymentLiquidityVariables = Exact<{ - input: WithdrawIncomingPaymentLiquidityInput; +export type CreateIncomingPaymentWithdrawalVariables = Exact<{ + input: CreateIncomingPaymentWithdrawalInput; }>; -export type WithdrawIncomingPaymentLiquidity = { __typename?: 'Mutation', withdrawIncomingPaymentLiquidity?: { __typename?: 'LiquidityMutationResponse', success: boolean, message: string } | null }; +export type CreateIncomingPaymentWithdrawal = { __typename?: 'Mutation', createIncomingPaymentWithdrawal?: { __typename?: 'LiquidityMutationResponse', success: boolean, message: string } | null }; export type GetPeerQueryVariables = Exact<{ id: Scalars['String']['input']; diff --git a/packages/frontend/app/lib/api/payments.server.ts b/packages/frontend/app/lib/api/payments.server.ts index a8300ee67d..11540e527e 100644 --- a/packages/frontend/app/lib/api/payments.server.ts +++ b/packages/frontend/app/lib/api/payments.server.ts @@ -2,12 +2,12 @@ import { gql } from '@apollo/client' import type { ListPaymentsQuery, ListPaymentsQueryVariables, - WithdrawIncomingPaymentLiquidity, - WithdrawIncomingPaymentLiquidityVariables, - WithdrawIncomingPaymentLiquidityInput, - WithdrawOutgoingPaymentLiquidity, - WithdrawOutgoingPaymentLiquidityVariables, - WithdrawOutgoingPaymentLiquidityInput, + CreateIncomingPaymentWithdrawal, + CreateIncomingPaymentWithdrawalVariables, + CreateIncomingPaymentWithdrawalInput, + CreateOutgoingPaymentWithdrawal, + CreateOutgoingPaymentWithdrawalVariables, + CreateOutgoingPaymentWithdrawalInput, DepositOutgoingPaymentLiquidityInput, DepositOutgoingPaymentLiquidity, DepositOutgoingPaymentLiquidityVariables @@ -164,18 +164,18 @@ export const depositOutgoingPaymentLiquidity = async ( return response.data?.depositOutgoingPaymentLiquidity } -export const withdrawOutgoingPaymentLiquidity = async ( - args: WithdrawOutgoingPaymentLiquidityInput +export const createOutgoingPaymentWithdrawal = async ( + args: CreateOutgoingPaymentWithdrawalInput ) => { const response = await apolloClient.mutate< - WithdrawOutgoingPaymentLiquidity, - WithdrawOutgoingPaymentLiquidityVariables + CreateOutgoingPaymentWithdrawal, + CreateOutgoingPaymentWithdrawalVariables >({ mutation: gql` - mutation WithdrawOutgoingPaymentLiquidity( - $input: WithdrawOutgoingPaymentLiquidityInput! + mutation CreateOutgoingPaymentWithdrawal( + $input: CreateOutgoingPaymentWithdrawalInput! ) { - withdrawOutgoingPaymentLiquidity(input: $input) { + createOutgoingPaymentWithdrawal(input: $input) { success message } @@ -186,21 +186,21 @@ export const withdrawOutgoingPaymentLiquidity = async ( } }) - return response.data?.withdrawOutgoingPaymentLiquidity + return response.data?.createOutgoingPaymentWithdrawal } -export const withdrawIncomingPaymentLiquidity = async ( - args: WithdrawIncomingPaymentLiquidityInput +export const createIncomingPaymentWithdrawal = async ( + args: CreateIncomingPaymentWithdrawalInput ) => { const response = await apolloClient.mutate< - WithdrawIncomingPaymentLiquidity, - WithdrawIncomingPaymentLiquidityVariables + CreateIncomingPaymentWithdrawal, + CreateIncomingPaymentWithdrawalVariables >({ mutation: gql` - mutation WithdrawIncomingPaymentLiquidity( - $input: WithdrawIncomingPaymentLiquidityInput! + mutation CreateIncomingPaymentWithdrawal( + $input: CreateIncomingPaymentWithdrawalInput! ) { - withdrawIncomingPaymentLiquidity(input: $input) { + createIncomingPaymentWithdrawal(input: $input) { success message } @@ -211,5 +211,5 @@ export const withdrawIncomingPaymentLiquidity = async ( } }) - return response.data?.withdrawIncomingPaymentLiquidity + return response.data?.createIncomingPaymentWithdrawal } diff --git a/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx b/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx index dc64314aab..2bf52d24f4 100644 --- a/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/assets.$assetId.withdraw-liquidity.tsx @@ -5,7 +5,7 @@ import { LiquidityDialog } from '~/components/LiquidityDialog' import { withdrawAssetLiquidity } from '~/lib/api/asset.server' import { messageStorage, setMessageAndRedirect } from '~/lib/message.server' import { amountSchema } from '~/lib/validate.server' -import { redirectIfUnauthorizedAccess } from '../lib/kratos_checks.server' +import { redirectIfUnauthorizedAccess } from '~/lib/kratos_checks.server' import { type LoaderFunctionArgs } from '@remix-run/node' export const loader = async ({ request }: LoaderFunctionArgs) => { @@ -60,7 +60,8 @@ export async function action({ request, params }: ActionFunctionArgs) { assetId, amount: result.data, id: v4(), - idempotencyKey: v4() + idempotencyKey: v4(), + timeoutSeconds: BigInt(0) }) if (!response?.success) { diff --git a/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx b/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx index a96c33845c..8fe1ba6635 100644 --- a/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/payments.incoming.$incomingPaymentId.withdraw-liquidity.tsx @@ -2,7 +2,7 @@ import { type ActionFunctionArgs } from '@remix-run/node' import { useNavigate, useOutletContext } from '@remix-run/react' import { v4 } from 'uuid' import { LiquidityConfirmDialog } from '~/components/LiquidityConfirmDialog' -import { withdrawIncomingPaymentLiquidity } from '~/lib/api/payments.server' +import { createIncomingPaymentWithdrawal } from '~/lib/api/payments.server' import { messageStorage, setMessageAndRedirect } from '~/lib/message.server' import { redirectIfUnauthorizedAccess } from '../lib/kratos_checks.server' import { type LoaderFunctionArgs } from '@remix-run/node' @@ -43,9 +43,10 @@ export async function action({ request, params }: ActionFunctionArgs) { }) } - const response = await withdrawIncomingPaymentLiquidity({ + const response = await createIncomingPaymentWithdrawal({ incomingPaymentId, - idempotencyKey: v4() + idempotencyKey: v4(), + timeoutSeconds: BigInt(0) }) if (!response?.success) { diff --git a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx index 0cb206fe0a..f8f0eb993f 100644 --- a/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/payments.outgoing.$outgoingPaymentId.withdraw-liquidity.tsx @@ -2,7 +2,7 @@ import { type ActionFunctionArgs } from '@remix-run/node' import { useNavigate, useOutletContext } from '@remix-run/react' import { v4 } from 'uuid' import { LiquidityConfirmDialog } from '~/components/LiquidityConfirmDialog' -import { withdrawOutgoingPaymentLiquidity } from '~/lib/api/payments.server' +import { createOutgoingPaymentWithdrawal } from '~/lib/api/payments.server' import { messageStorage, setMessageAndRedirect } from '~/lib/message.server' import type { LiquidityActionOutletContext } from './payments.outgoing.$outgoingPaymentId' import { redirectIfUnauthorizedAccess } from '../lib/kratos_checks.server' @@ -45,9 +45,10 @@ export async function action({ request, params }: ActionFunctionArgs) { }) } - const response = await withdrawOutgoingPaymentLiquidity({ + const response = await createOutgoingPaymentWithdrawal({ outgoingPaymentId, - idempotencyKey: v4() + idempotencyKey: v4(), + timeoutSeconds: BigInt(0) }) if (!response?.success) { diff --git a/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx b/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx index 02fa21f6f0..d48a558e14 100644 --- a/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/peers.$peerId.withdraw-liquidity.tsx @@ -60,7 +60,8 @@ export async function action({ request, params }: ActionFunctionArgs) { peerId, amount: result.data, id: v4(), - idempotencyKey: v4() + idempotencyKey: v4(), + timeoutSeconds: BigInt(0) }) if (!response?.success) { diff --git a/packages/frontend/app/routes/wallet-addresses.$walletAddressId.withdraw-liquidity.tsx b/packages/frontend/app/routes/wallet-addresses.$walletAddressId.withdraw-liquidity.tsx index b19273baf2..8f15df05db 100644 --- a/packages/frontend/app/routes/wallet-addresses.$walletAddressId.withdraw-liquidity.tsx +++ b/packages/frontend/app/routes/wallet-addresses.$walletAddressId.withdraw-liquidity.tsx @@ -46,7 +46,8 @@ export async function action({ request, params }: ActionFunctionArgs) { const response = await createWalletAddressWithdrawal({ id: v4(), walletAddressId, - idempotencyKey: v4() + idempotencyKey: v4(), + timeoutSeconds: BigInt(0) }) if (!response?.success) { diff --git a/packages/mock-account-service-lib/src/generated/graphql.ts b/packages/mock-account-service-lib/src/generated/graphql.ts index 61ebb6868b..0de5e4b8f0 100644 --- a/packages/mock-account-service-lib/src/generated/graphql.ts +++ b/packages/mock-account-service-lib/src/generated/graphql.ts @@ -130,6 +130,8 @@ export type CreateAssetLiquidityWithdrawalInput = { id: Scalars['String']['input']; /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; }; export type CreateIncomingPaymentInput = { @@ -145,6 +147,15 @@ export type CreateIncomingPaymentInput = { walletAddressId: Scalars['String']['input']; }; +export type CreateIncomingPaymentWithdrawalInput = { + /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ + idempotencyKey: Scalars['String']['input']; + /** The id of the incoming payment to withdraw from. */ + incomingPaymentId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; +}; + export type CreateOrUpdatePeerByUrlInput = { /** Asset id of peering relationship */ assetId: Scalars['String']['input']; @@ -194,6 +205,15 @@ export type CreateOutgoingPaymentInput = { walletAddressId: Scalars['String']['input']; }; +export type CreateOutgoingPaymentWithdrawalInput = { + /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ + idempotencyKey: Scalars['String']['input']; + /** The id of the outgoing payment to withdraw from. */ + outgoingPaymentId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; +}; + export type CreatePeerInput = { /** Asset id of peering relationship */ assetId: Scalars['String']['input']; @@ -222,6 +242,8 @@ export type CreatePeerLiquidityWithdrawalInput = { idempotencyKey: Scalars['String']['input']; /** The id of the peer to create the withdrawal for. */ peerId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; }; export type CreatePeerMutationResponse = MutationResponse & { @@ -306,6 +328,8 @@ export type CreateWalletAddressWithdrawalInput = { id: Scalars['String']['input']; /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; /** The id of the Open Payments wallet address to create the withdrawal for. */ walletAddressId: Scalars['String']['input']; }; @@ -566,12 +590,16 @@ export type Mutation = { createAssetLiquidityWithdrawal?: Maybe; /** Create an internal Open Payments Incoming Payment. The receiver has a wallet address on this Rafiki instance. */ createIncomingPayment: IncomingPaymentResponse; + /** Withdraw incoming payment liquidity */ + createIncomingPaymentWithdrawal?: Maybe; /** Create a peer using a URL */ createOrUpdatePeerByUrl: CreateOrUpdatePeerByUrlMutationResponse; /** Create an Open Payments Outgoing Payment */ createOutgoingPayment: OutgoingPaymentResponse; /** Create an Open Payments Outgoing Payment from an incoming payment */ createOutgoingPaymentFromIncomingPayment: OutgoingPaymentResponse; + /** Withdraw outgoing payment liquidity */ + createOutgoingPaymentWithdrawal?: Maybe; /** Create a peer */ createPeer: CreatePeerMutationResponse; /** Withdraw peer liquidity */ @@ -617,13 +645,9 @@ export type Mutation = { voidLiquidityWithdrawal?: Maybe; /** * Withdraw webhook event liquidity - * @deprecated Use `withdrawOutgoingPaymentLiquidity, withdrawIncomingPaymentLiquidity, or createWalletAddressWithdrawal` + * @deprecated Use `createOutgoingPaymentWithdrawal, createIncomingPaymentWithdrawal, or createWalletAddressWithdrawal` */ withdrawEventLiquidity?: Maybe; - /** Withdraw incoming payment liquidity */ - withdrawIncomingPaymentLiquidity?: Maybe; - /** Withdraw outgoing payment liquidity */ - withdrawOutgoingPaymentLiquidity?: Maybe; }; @@ -647,6 +671,11 @@ export type MutationCreateIncomingPaymentArgs = { }; +export type MutationCreateIncomingPaymentWithdrawalArgs = { + input: CreateIncomingPaymentWithdrawalInput; +}; + + export type MutationCreateOrUpdatePeerByUrlArgs = { input: CreateOrUpdatePeerByUrlInput; }; @@ -662,6 +691,11 @@ export type MutationCreateOutgoingPaymentFromIncomingPaymentArgs = { }; +export type MutationCreateOutgoingPaymentWithdrawalArgs = { + input: CreateOutgoingPaymentWithdrawalInput; +}; + + export type MutationCreatePeerArgs = { input: CreatePeerInput; }; @@ -766,16 +800,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; - -export type MutationWithdrawIncomingPaymentLiquidityArgs = { - input: WithdrawIncomingPaymentLiquidityInput; -}; - - -export type MutationWithdrawOutgoingPaymentLiquidityArgs = { - input: WithdrawOutgoingPaymentLiquidityInput; -}; - export type MutationResponse = { code: Scalars['String']['output']; message: Scalars['String']['output']; @@ -1404,20 +1428,6 @@ export type WithdrawEventLiquidityInput = { idempotencyKey: Scalars['String']['input']; }; -export type WithdrawIncomingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the incoming payment to withdraw from. */ - incomingPaymentId: Scalars['String']['input']; -}; - -export type WithdrawOutgoingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the outgoing payment to withdraw from. */ - outgoingPaymentId: Scalars['String']['input']; -}; - export type ResolverTypeWrapper = Promise | T; @@ -1508,10 +1518,12 @@ export type ResolversTypes = { CreateAssetInput: ResolverTypeWrapper>; CreateAssetLiquidityWithdrawalInput: ResolverTypeWrapper>; CreateIncomingPaymentInput: ResolverTypeWrapper>; + CreateIncomingPaymentWithdrawalInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlMutationResponse: ResolverTypeWrapper>; CreateOutgoingPaymentFromIncomingPaymentInput: ResolverTypeWrapper>; CreateOutgoingPaymentInput: ResolverTypeWrapper>; + CreateOutgoingPaymentWithdrawalInput: ResolverTypeWrapper>; CreatePeerInput: ResolverTypeWrapper>; CreatePeerLiquidityWithdrawalInput: ResolverTypeWrapper>; CreatePeerMutationResponse: ResolverTypeWrapper>; @@ -1610,8 +1622,6 @@ export type ResolversTypes = { WebhookEventsConnection: ResolverTypeWrapper>; WebhookEventsEdge: ResolverTypeWrapper>; WithdrawEventLiquidityInput: ResolverTypeWrapper>; - WithdrawIncomingPaymentLiquidityInput: ResolverTypeWrapper>; - WithdrawOutgoingPaymentLiquidityInput: ResolverTypeWrapper>; }; /** Mapping between all available schema types and the resolvers parents */ @@ -1628,10 +1638,12 @@ export type ResolversParentTypes = { CreateAssetInput: Partial; CreateAssetLiquidityWithdrawalInput: Partial; CreateIncomingPaymentInput: Partial; + CreateIncomingPaymentWithdrawalInput: Partial; CreateOrUpdatePeerByUrlInput: Partial; CreateOrUpdatePeerByUrlMutationResponse: Partial; CreateOutgoingPaymentFromIncomingPaymentInput: Partial; CreateOutgoingPaymentInput: Partial; + CreateOutgoingPaymentWithdrawalInput: Partial; CreatePeerInput: Partial; CreatePeerLiquidityWithdrawalInput: Partial; CreatePeerMutationResponse: Partial; @@ -1721,8 +1733,6 @@ export type ResolversParentTypes = { WebhookEventsConnection: Partial; WebhookEventsEdge: Partial; WithdrawEventLiquidityInput: Partial; - WithdrawIncomingPaymentLiquidityInput: Partial; - WithdrawOutgoingPaymentLiquidityInput: Partial; }; export type AmountResolvers = { @@ -1921,9 +1931,11 @@ export type MutationResolvers>; createAssetLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createIncomingPayment?: Resolver>; + createIncomingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createOrUpdatePeerByUrl?: Resolver>; createOutgoingPayment?: Resolver>; createOutgoingPaymentFromIncomingPayment?: Resolver>; + createOutgoingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createPeer?: Resolver>; createPeerLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createQuote?: Resolver>; @@ -1945,8 +1957,6 @@ export type MutationResolvers>; voidLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; withdrawEventLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawIncomingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawOutgoingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; }; export type MutationResponseResolvers = { diff --git a/test/integration/lib/generated/graphql.ts b/test/integration/lib/generated/graphql.ts index 61ebb6868b..0de5e4b8f0 100644 --- a/test/integration/lib/generated/graphql.ts +++ b/test/integration/lib/generated/graphql.ts @@ -130,6 +130,8 @@ export type CreateAssetLiquidityWithdrawalInput = { id: Scalars['String']['input']; /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; }; export type CreateIncomingPaymentInput = { @@ -145,6 +147,15 @@ export type CreateIncomingPaymentInput = { walletAddressId: Scalars['String']['input']; }; +export type CreateIncomingPaymentWithdrawalInput = { + /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ + idempotencyKey: Scalars['String']['input']; + /** The id of the incoming payment to withdraw from. */ + incomingPaymentId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; +}; + export type CreateOrUpdatePeerByUrlInput = { /** Asset id of peering relationship */ assetId: Scalars['String']['input']; @@ -194,6 +205,15 @@ export type CreateOutgoingPaymentInput = { walletAddressId: Scalars['String']['input']; }; +export type CreateOutgoingPaymentWithdrawalInput = { + /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ + idempotencyKey: Scalars['String']['input']; + /** The id of the outgoing payment to withdraw from. */ + outgoingPaymentId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; +}; + export type CreatePeerInput = { /** Asset id of peering relationship */ assetId: Scalars['String']['input']; @@ -222,6 +242,8 @@ export type CreatePeerLiquidityWithdrawalInput = { idempotencyKey: Scalars['String']['input']; /** The id of the peer to create the withdrawal for. */ peerId: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; }; export type CreatePeerMutationResponse = MutationResponse & { @@ -306,6 +328,8 @@ export type CreateWalletAddressWithdrawalInput = { id: Scalars['String']['input']; /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ idempotencyKey: Scalars['String']['input']; + /** This is the interval in seconds after a pending transfer's created at which it may be posted or voided. Zero denotes a no timeout single-phase posted transfer. */ + timeoutSeconds: Scalars['UInt64']['input']; /** The id of the Open Payments wallet address to create the withdrawal for. */ walletAddressId: Scalars['String']['input']; }; @@ -566,12 +590,16 @@ export type Mutation = { createAssetLiquidityWithdrawal?: Maybe; /** Create an internal Open Payments Incoming Payment. The receiver has a wallet address on this Rafiki instance. */ createIncomingPayment: IncomingPaymentResponse; + /** Withdraw incoming payment liquidity */ + createIncomingPaymentWithdrawal?: Maybe; /** Create a peer using a URL */ createOrUpdatePeerByUrl: CreateOrUpdatePeerByUrlMutationResponse; /** Create an Open Payments Outgoing Payment */ createOutgoingPayment: OutgoingPaymentResponse; /** Create an Open Payments Outgoing Payment from an incoming payment */ createOutgoingPaymentFromIncomingPayment: OutgoingPaymentResponse; + /** Withdraw outgoing payment liquidity */ + createOutgoingPaymentWithdrawal?: Maybe; /** Create a peer */ createPeer: CreatePeerMutationResponse; /** Withdraw peer liquidity */ @@ -617,13 +645,9 @@ export type Mutation = { voidLiquidityWithdrawal?: Maybe; /** * Withdraw webhook event liquidity - * @deprecated Use `withdrawOutgoingPaymentLiquidity, withdrawIncomingPaymentLiquidity, or createWalletAddressWithdrawal` + * @deprecated Use `createOutgoingPaymentWithdrawal, createIncomingPaymentWithdrawal, or createWalletAddressWithdrawal` */ withdrawEventLiquidity?: Maybe; - /** Withdraw incoming payment liquidity */ - withdrawIncomingPaymentLiquidity?: Maybe; - /** Withdraw outgoing payment liquidity */ - withdrawOutgoingPaymentLiquidity?: Maybe; }; @@ -647,6 +671,11 @@ export type MutationCreateIncomingPaymentArgs = { }; +export type MutationCreateIncomingPaymentWithdrawalArgs = { + input: CreateIncomingPaymentWithdrawalInput; +}; + + export type MutationCreateOrUpdatePeerByUrlArgs = { input: CreateOrUpdatePeerByUrlInput; }; @@ -662,6 +691,11 @@ export type MutationCreateOutgoingPaymentFromIncomingPaymentArgs = { }; +export type MutationCreateOutgoingPaymentWithdrawalArgs = { + input: CreateOutgoingPaymentWithdrawalInput; +}; + + export type MutationCreatePeerArgs = { input: CreatePeerInput; }; @@ -766,16 +800,6 @@ export type MutationWithdrawEventLiquidityArgs = { input: WithdrawEventLiquidityInput; }; - -export type MutationWithdrawIncomingPaymentLiquidityArgs = { - input: WithdrawIncomingPaymentLiquidityInput; -}; - - -export type MutationWithdrawOutgoingPaymentLiquidityArgs = { - input: WithdrawOutgoingPaymentLiquidityInput; -}; - export type MutationResponse = { code: Scalars['String']['output']; message: Scalars['String']['output']; @@ -1404,20 +1428,6 @@ export type WithdrawEventLiquidityInput = { idempotencyKey: Scalars['String']['input']; }; -export type WithdrawIncomingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the incoming payment to withdraw from. */ - incomingPaymentId: Scalars['String']['input']; -}; - -export type WithdrawOutgoingPaymentLiquidityInput = { - /** Unique key to ensure duplicate or retried requests are processed only once. See [idempotence](https://en.wikipedia.org/wiki/Idempotence) */ - idempotencyKey: Scalars['String']['input']; - /** The id of the outgoing payment to withdraw from. */ - outgoingPaymentId: Scalars['String']['input']; -}; - export type ResolverTypeWrapper = Promise | T; @@ -1508,10 +1518,12 @@ export type ResolversTypes = { CreateAssetInput: ResolverTypeWrapper>; CreateAssetLiquidityWithdrawalInput: ResolverTypeWrapper>; CreateIncomingPaymentInput: ResolverTypeWrapper>; + CreateIncomingPaymentWithdrawalInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlInput: ResolverTypeWrapper>; CreateOrUpdatePeerByUrlMutationResponse: ResolverTypeWrapper>; CreateOutgoingPaymentFromIncomingPaymentInput: ResolverTypeWrapper>; CreateOutgoingPaymentInput: ResolverTypeWrapper>; + CreateOutgoingPaymentWithdrawalInput: ResolverTypeWrapper>; CreatePeerInput: ResolverTypeWrapper>; CreatePeerLiquidityWithdrawalInput: ResolverTypeWrapper>; CreatePeerMutationResponse: ResolverTypeWrapper>; @@ -1610,8 +1622,6 @@ export type ResolversTypes = { WebhookEventsConnection: ResolverTypeWrapper>; WebhookEventsEdge: ResolverTypeWrapper>; WithdrawEventLiquidityInput: ResolverTypeWrapper>; - WithdrawIncomingPaymentLiquidityInput: ResolverTypeWrapper>; - WithdrawOutgoingPaymentLiquidityInput: ResolverTypeWrapper>; }; /** Mapping between all available schema types and the resolvers parents */ @@ -1628,10 +1638,12 @@ export type ResolversParentTypes = { CreateAssetInput: Partial; CreateAssetLiquidityWithdrawalInput: Partial; CreateIncomingPaymentInput: Partial; + CreateIncomingPaymentWithdrawalInput: Partial; CreateOrUpdatePeerByUrlInput: Partial; CreateOrUpdatePeerByUrlMutationResponse: Partial; CreateOutgoingPaymentFromIncomingPaymentInput: Partial; CreateOutgoingPaymentInput: Partial; + CreateOutgoingPaymentWithdrawalInput: Partial; CreatePeerInput: Partial; CreatePeerLiquidityWithdrawalInput: Partial; CreatePeerMutationResponse: Partial; @@ -1721,8 +1733,6 @@ export type ResolversParentTypes = { WebhookEventsConnection: Partial; WebhookEventsEdge: Partial; WithdrawEventLiquidityInput: Partial; - WithdrawIncomingPaymentLiquidityInput: Partial; - WithdrawOutgoingPaymentLiquidityInput: Partial; }; export type AmountResolvers = { @@ -1921,9 +1931,11 @@ export type MutationResolvers>; createAssetLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createIncomingPayment?: Resolver>; + createIncomingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createOrUpdatePeerByUrl?: Resolver>; createOutgoingPayment?: Resolver>; createOutgoingPaymentFromIncomingPayment?: Resolver>; + createOutgoingPaymentWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createPeer?: Resolver>; createPeerLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; createQuote?: Resolver>; @@ -1945,8 +1957,6 @@ export type MutationResolvers>; voidLiquidityWithdrawal?: Resolver, ParentType, ContextType, RequireFields>; withdrawEventLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawIncomingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; - withdrawOutgoingPaymentLiquidity?: Resolver, ParentType, ContextType, RequireFields>; }; export type MutationResponseResolvers = {