From acac09f6bf05fca534b375e3dcef10e70bc718a8 Mon Sep 17 00:00:00 2001 From: flopez7 Date: Fri, 20 Mar 2026 14:56:53 +0100 Subject: [PATCH] add cancellationRequestedAt field to Escrow data model and related functionality --- .changeset/wide-islands-leave.md | 6 ++++ .../human_protocol_sdk/escrow/escrow_utils.py | 10 +++++++ .../human_protocol_sdk/gql/escrow.py | 1 + .../escrow/test_escrow_utils.py | 14 +++++++++ .../src/escrow/escrow_utils.ts | 3 ++ .../src/graphql/queries/escrow.ts | 1 + .../human-protocol-sdk/src/graphql/types.ts | 1 + .../human-protocol-sdk/src/interfaces.ts | 1 + .../human-protocol-sdk/test/escrow.test.ts | 30 +++++++++++++++++++ .../subgraph/human-protocol/schema.graphql | 1 + .../src/mapping/EscrowTemplate.ts | 1 + .../tests/escrow/escrow.test.ts | 6 ++++ 12 files changed, 75 insertions(+) create mode 100644 .changeset/wide-islands-leave.md diff --git a/.changeset/wide-islands-leave.md b/.changeset/wide-islands-leave.md new file mode 100644 index 0000000000..51b690e50b --- /dev/null +++ b/.changeset/wide-islands-leave.md @@ -0,0 +1,6 @@ +--- +"@human-protocol/sdk": minor +"@human-protocol/python-sdk": minor +--- + +Add cancellationRequestedAt field to Escrow data model diff --git a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/escrow/escrow_utils.py b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/escrow/escrow_utils.py index 2c08b7d1b9..33eedb0e53 100644 --- a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/escrow/escrow_utils.py +++ b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/escrow/escrow_utils.py @@ -68,6 +68,8 @@ class EscrowData: token (str): Address of the payment token. total_funded_amount (int): Total amount funded to the escrow. created_at (int): Creation timestamp in milliseconds. + cancellation_requested_at (Optional[int]): Cancellation request timestamp in + milliseconds. chain_id (ChainId): Chain where the escrow is deployed. """ @@ -86,6 +88,7 @@ def __init__( token: str, total_funded_amount: str, created_at: str, + cancellation_requested_at: Optional[str] = None, final_results_url: Optional[str] = None, final_results_hash: Optional[str] = None, intermediate_results_url: Optional[str] = None, @@ -129,6 +132,11 @@ def __init__( self.token = token self.total_funded_amount = int(total_funded_amount) self.created_at = int(created_at) * 1000 + self.cancellation_requested_at = ( + int(cancellation_requested_at) * 1000 + if cancellation_requested_at is not None + else None + ) self.chain_id = chain_id @@ -325,6 +333,7 @@ def get_escrows( token=escrow.get("token"), total_funded_amount=escrow.get("totalFundedAmount"), created_at=escrow.get("createdAt"), + cancellation_requested_at=escrow.get("cancellationRequestedAt"), final_results_url=escrow.get("finalResultsUrl"), final_results_hash=escrow.get("finalResultsHash"), intermediate_results_url=escrow.get("intermediateResultsUrl"), @@ -423,6 +432,7 @@ def get_escrow( token=escrow.get("token"), total_funded_amount=escrow.get("totalFundedAmount"), created_at=escrow.get("createdAt"), + cancellation_requested_at=escrow.get("cancellationRequestedAt"), final_results_url=escrow.get("finalResultsUrl"), final_results_hash=escrow.get("finalResultsHash"), intermediate_results_url=escrow.get("intermediateResultsUrl"), diff --git a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/gql/escrow.py b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/gql/escrow.py index 528de7d944..d856b7780f 100644 --- a/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/gql/escrow.py +++ b/packages/sdk/python/human-protocol-sdk/human_protocol_sdk/gql/escrow.py @@ -27,6 +27,7 @@ token totalFundedAmount createdAt + cancellationRequestedAt } """ diff --git a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/escrow/test_escrow_utils.py b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/escrow/test_escrow_utils.py index 98158e7358..42d8a81e51 100644 --- a/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/escrow/test_escrow_utils.py +++ b/packages/sdk/python/human-protocol-sdk/test/human_protocol_sdk/escrow/test_escrow_utils.py @@ -49,6 +49,7 @@ def test_get_escrows(self): "token": "0x1234567890123456789012345678901234567891", "totalFundedAmount": "1000000000000000000", "createdAt": "1683811973", + "cancellationRequestedAt": "1683812000", } def side_effect(subgraph_url, query, params, options): @@ -134,6 +135,10 @@ def side_effect(subgraph_url, query, params, options): self.assertEqual( int(filtered[0].created_at), int(mock_escrow["createdAt"]) * 1000 ) + self.assertEqual( + int(filtered[0].cancellation_requested_at), + int(mock_escrow["cancellationRequestedAt"]) * 1000, + ) filter = EscrowFilter(chain_id=ChainId.POLYGON_AMOY) @@ -184,6 +189,7 @@ def test_get_escrows_with_status_array(self): "token": "0x1234567890123456789012345678901234567891", "totalFundedAmount": "1000000000000000000", "createdAt": "1672531200000", + "cancellationRequestedAt": None, } mock_escrow_2 = { "id": "0x1234567890123456789012345678901234567891", @@ -204,6 +210,7 @@ def test_get_escrows_with_status_array(self): "token": "0x1234567890123456789012345678901234567891", "totalFundedAmount": "1000000000000000000", "createdAt": "1672531200000", + "cancellationRequestedAt": None, } def side_effect(subgraph_url, query, params, options): @@ -239,6 +246,8 @@ def side_effect(subgraph_url, query, params, options): self.assertEqual(len(filtered), 2) self.assertEqual(filtered[0].address, mock_escrow_1["address"]) self.assertEqual(filtered[1].address, mock_escrow_2["address"]) + self.assertIsNone(filtered[0].cancellation_requested_at) + self.assertIsNone(filtered[1].cancellation_requested_at) def test_get_escrow(self): with patch( @@ -268,6 +277,7 @@ def test_get_escrow(self): "token": "0x1234567890123456789012345678901234567891", "totalFundedAmount": "1000000000000000000", "createdAt": "1683813973", + "cancellationRequestedAt": "1683814000", } mock_function.return_value = { @@ -326,6 +336,10 @@ def test_get_escrow(self): self.assertEqual( int(escrow.created_at), int(mock_escrow["createdAt"]) * 1000 ) + self.assertEqual( + int(escrow.cancellation_requested_at), + int(mock_escrow["cancellationRequestedAt"]) * 1000, + ) def test_get_escrow_empty_data(self): with patch( diff --git a/packages/sdk/typescript/human-protocol-sdk/src/escrow/escrow_utils.ts b/packages/sdk/typescript/human-protocol-sdk/src/escrow/escrow_utils.ts index ff3e582a4b..93727c1379 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/escrow/escrow_utils.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/escrow/escrow_utils.ts @@ -513,6 +513,9 @@ function mapEscrow(e: EscrowData, chainId: ChainId | number): IEscrow { token: e.token, totalFundedAmount: BigInt(e.totalFundedAmount), createdAt: Number(e.createdAt) * 1000, + cancellationRequestedAt: e.cancellationRequestedAt + ? Number(e.cancellationRequestedAt) * 1000 + : null, chainId: Number(chainId), }; } diff --git a/packages/sdk/typescript/human-protocol-sdk/src/graphql/queries/escrow.ts b/packages/sdk/typescript/human-protocol-sdk/src/graphql/queries/escrow.ts index 64cd13a781..9faea4ecbd 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/graphql/queries/escrow.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/graphql/queries/escrow.ts @@ -27,6 +27,7 @@ const ESCROW_FRAGMENT = gql` token totalFundedAmount createdAt + cancellationRequestedAt } `; diff --git a/packages/sdk/typescript/human-protocol-sdk/src/graphql/types.ts b/packages/sdk/typescript/human-protocol-sdk/src/graphql/types.ts index 928d37fffe..3945d68bcf 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/graphql/types.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/graphql/types.ts @@ -25,6 +25,7 @@ export type EscrowData = { token: string; totalFundedAmount: string; createdAt: string; + cancellationRequestedAt: string | null; }; export type WorkerData = { diff --git a/packages/sdk/typescript/human-protocol-sdk/src/interfaces.ts b/packages/sdk/typescript/human-protocol-sdk/src/interfaces.ts index 0719d1d033..11fc04bcd7 100644 --- a/packages/sdk/typescript/human-protocol-sdk/src/interfaces.ts +++ b/packages/sdk/typescript/human-protocol-sdk/src/interfaces.ts @@ -68,6 +68,7 @@ export interface IEscrow { token: string; totalFundedAmount: bigint; createdAt: number; + cancellationRequestedAt: number | null; chainId: number; } diff --git a/packages/sdk/typescript/human-protocol-sdk/test/escrow.test.ts b/packages/sdk/typescript/human-protocol-sdk/test/escrow.test.ts index ac9e09262c..15e16a301c 100644 --- a/packages/sdk/typescript/human-protocol-sdk/test/escrow.test.ts +++ b/packages/sdk/typescript/human-protocol-sdk/test/escrow.test.ts @@ -3472,6 +3472,7 @@ describe('EscrowUtils', () => { token: '0x0', totalFundedAmount: '3', createdAt: '1', + cancellationRequestedAt: '2', finalResultsHash: null, finalResultsUrl: null, intermediateResultsHash: null, @@ -3498,6 +3499,7 @@ describe('EscrowUtils', () => { token: '0x0', totalFundedAmount: '3', createdAt: '1', + cancellationRequestedAt: null, finalResultsHash: null, finalResultsUrl: null, intermediateResultsHash: null, @@ -3529,6 +3531,9 @@ describe('EscrowUtils', () => { count: Number(e.count), totalFundedAmount: BigInt(e.totalFundedAmount), createdAt: Number(e.createdAt) * 1000, + cancellationRequestedAt: e.cancellationRequestedAt + ? Number(e.cancellationRequestedAt) * 1000 + : null, recordingOracleFee: e.recordingOracleFee ? Number(e.recordingOracleFee) : null, @@ -3570,6 +3575,7 @@ describe('EscrowUtils', () => { balance: '0', count: '1', createdAt: '1', + cancellationRequestedAt: null, factoryAddress: '0x0', launcher: '0x0', status: 'Pending', @@ -3596,6 +3602,7 @@ describe('EscrowUtils', () => { balance: '0', count: '1', createdAt: '1', + cancellationRequestedAt: null, factoryAddress: '0x0', launcher: '0x0', status: 'Complete', @@ -3632,6 +3639,9 @@ describe('EscrowUtils', () => { count: Number(e.count), totalFundedAmount: BigInt(e.totalFundedAmount), createdAt: Number(e.createdAt) * 1000, + cancellationRequestedAt: e.cancellationRequestedAt + ? Number(e.cancellationRequestedAt) * 1000 + : null, recordingOracleFee: e.recordingOracleFee ? Number(e.recordingOracleFee) : null, @@ -3656,6 +3666,7 @@ describe('EscrowUtils', () => { balance: '0', count: '1', createdAt: '1', + cancellationRequestedAt: null, factoryAddress: '0x0', launcher: '0x0', status: 'Completed', @@ -3692,6 +3703,9 @@ describe('EscrowUtils', () => { count: Number(e.count), totalFundedAmount: BigInt(e.totalFundedAmount), createdAt: Number(e.createdAt) * 1000, + cancellationRequestedAt: e.cancellationRequestedAt + ? Number(e.cancellationRequestedAt) * 1000 + : null, recordingOracleFee: e.recordingOracleFee ? Number(e.recordingOracleFee) : null, @@ -3717,6 +3731,7 @@ describe('EscrowUtils', () => { count: '1', jobRequesterId: '1', createdAt: '1', + cancellationRequestedAt: null, factoryAddress: '0x0', launcher: '0x0', status: 'Completed', @@ -3752,6 +3767,9 @@ describe('EscrowUtils', () => { count: Number(e.count), totalFundedAmount: BigInt(e.totalFundedAmount), createdAt: Number(e.createdAt) * 1000, + cancellationRequestedAt: e.cancellationRequestedAt + ? Number(e.cancellationRequestedAt) * 1000 + : null, recordingOracleFee: e.recordingOracleFee ? Number(e.recordingOracleFee) : null, @@ -3776,6 +3794,7 @@ describe('EscrowUtils', () => { balance: '0', count: '1', createdAt: '1', + cancellationRequestedAt: null, factoryAddress: '0x0', launcher: '0x0', status: 'Completed', @@ -3802,6 +3821,7 @@ describe('EscrowUtils', () => { balance: '3', count: '2', createdAt: '1', + cancellationRequestedAt: null, factoryAddress: '0x0', launcher: '0x0', status: 'Pending', @@ -3840,6 +3860,9 @@ describe('EscrowUtils', () => { count: Number(e.count), totalFundedAmount: BigInt(e.totalFundedAmount), createdAt: Number(e.createdAt) * 1000, + cancellationRequestedAt: e.cancellationRequestedAt + ? Number(e.cancellationRequestedAt) * 1000 + : null, recordingOracleFee: e.recordingOracleFee ? Number(e.recordingOracleFee) : null, @@ -3881,6 +3904,7 @@ describe('EscrowUtils', () => { balance: '0', count: '1', createdAt: '1', + cancellationRequestedAt: null, factoryAddress: '0x0', launcher: '0x0', status: 'Completed', @@ -3907,6 +3931,7 @@ describe('EscrowUtils', () => { balance: '3', count: '2', createdAt: '1', + cancellationRequestedAt: null, factoryAddress: '0x0', launcher: '0x0', status: 'Pending', @@ -3946,6 +3971,9 @@ describe('EscrowUtils', () => { count: Number(e.count), totalFundedAmount: BigInt(e.totalFundedAmount), createdAt: Number(e.createdAt) * 1000, + cancellationRequestedAt: e.cancellationRequestedAt + ? Number(e.cancellationRequestedAt) * 1000 + : null, recordingOracleFee: e.recordingOracleFee ? Number(e.recordingOracleFee) : undefined, @@ -4025,6 +4053,7 @@ describe('EscrowUtils', () => { manifest: null, manifestHash: null, createdAt: '0', + cancellationRequestedAt: '12', }; const gqlFetchSpy = vi .spyOn(gqlFetch, 'default') @@ -4042,6 +4071,7 @@ describe('EscrowUtils', () => { reputationOracleFee: 1, exchangeOracleFee: 1, createdAt: 0, + cancellationRequestedAt: 12000, chainId, jobRequesterId: null, manifest: null, diff --git a/packages/subgraph/human-protocol/schema.graphql b/packages/subgraph/human-protocol/schema.graphql index 6204cc3577..0ef04b8193 100644 --- a/packages/subgraph/human-protocol/schema.graphql +++ b/packages/subgraph/human-protocol/schema.graphql @@ -67,6 +67,7 @@ type Escrow @entity(immutable: false) { intermediateResultsHash: String # string finalResultsUrl: String # string finalResultsHash: String # string + cancellationRequestedAt: BigInt jobRequesterId: String # string createdAt: BigInt! } diff --git a/packages/subgraph/human-protocol/src/mapping/EscrowTemplate.ts b/packages/subgraph/human-protocol/src/mapping/EscrowTemplate.ts index 88685f7332..f95775b45f 100644 --- a/packages/subgraph/human-protocol/src/mapping/EscrowTemplate.ts +++ b/packages/subgraph/human-protocol/src/mapping/EscrowTemplate.ts @@ -799,6 +799,7 @@ export function handleCancellationRequested( null, Address.fromBytes(escrowEntity.address) ); + escrowEntity.cancellationRequestedAt = event.block.timestamp; escrowEntity.status = 'ToCancel'; escrowEntity.save(); statusEventEntity.launcher = escrowEntity.launcher; diff --git a/packages/subgraph/human-protocol/tests/escrow/escrow.test.ts b/packages/subgraph/human-protocol/tests/escrow/escrow.test.ts index 26a8d442f1..096ee37968 100644 --- a/packages/subgraph/human-protocol/tests/escrow/escrow.test.ts +++ b/packages/subgraph/human-protocol/tests/escrow/escrow.test.ts @@ -1304,6 +1304,12 @@ describe('Escrow', () => { assert.fieldEquals('EscrowStatusEvent', id, 'status', 'ToCancel'); // Escrow + assert.fieldEquals( + 'Escrow', + escrowAddress.toHex(), + 'cancellationRequestedAt', + cancellationRequested.block.timestamp.toString() + ); assert.fieldEquals('Escrow', escrowAddress.toHex(), 'status', 'ToCancel'); assert.fieldEquals( 'Transaction',