From 83b6cc7996dbddb96237bbde626de227706c6e16 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Sun, 11 Oct 2026 06:17:52 +0000 Subject: [PATCH] chore: refresh store codegen snapshot --- packages/store/scripts/api-schema/schema.json | 6274 +++++++++++------ .../src/gateway/AUTO_GENERATED/.schema-hash | 2 +- .../src/gateway/AUTO_GENERATED/chains.ts | 3 + .../src/gateway/AUTO_GENERATED/delegates.ts | 93 + .../src/gateway/AUTO_GENERATED/messages.ts | 30 +- .../store/src/gateway/AUTO_GENERATED/relay.ts | 14 +- .../src/gateway/AUTO_GENERATED/spaces.ts | 39 +- .../gateway/AUTO_GENERATED/transactions.ts | 20 +- 8 files changed, 4435 insertions(+), 2040 deletions(-) diff --git a/packages/store/scripts/api-schema/schema.json b/packages/store/scripts/api-schema/schema.json index c87e9026418..18ab5ecd5bf 100644 --- a/packages/store/scripts/api-schema/schema.json +++ b/packages/store/scripts/api-schema/schema.json @@ -498,6 +498,9 @@ } } } + }, + "403": { + "description": "Not an admin" } }, "summary": "Get the billing portal session URL for a space", @@ -584,6 +587,12 @@ } } } + }, + "403": { + "description": "Not an admin, or a payment link this workspace is not offered" + }, + "409": { + "description": "This plan doesn't offer enough Safe seats for the workspace's current Safes" } }, "summary": "Create a checkout session for a payment link", @@ -592,6 +601,137 @@ ] } }, + "/v1/billing/spaces/{spaceId}/subscriptions/{subscriptionId}/preview-update": { + "get": { + "operationId": "billingPreviewSubscriptionUpdateV1", + "parameters": [ + { + "name": "subscriptionId", + "required": true, + "in": "path", + "description": "Subscription identifier", + "schema": { + "type": "string" + } + }, + { + "name": "planId", + "required": true, + "in": "query", + "description": "The price id of the plan to preview", + "schema": { + "type": "string" + } + }, + { + "name": "spaceId", + "required": true, + "in": "path", + "description": "Space UUID", + "schema": { + "example": "123e4567-e89b-12d3-a456-426614174000", + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SubscriptionUpdatePreview" + } + } + } + }, + "403": { + "description": "Not an admin, or a plan this workspace is not offered" + }, + "404": { + "description": "Subscription not found" + }, + "409": { + "description": "Already on this plan" + }, + "422": { + "description": "Malformed subscriptionId or planId" + } + }, + "summary": "Preview what moving a subscription to another plan would cost", + "tags": [ + "billing" + ] + } + }, + "/v1/billing/spaces/{spaceId}/subscriptions/{subscriptionId}": { + "patch": { + "description": "Safes in `removedSafes` are removed from the workspace first, then the plan changes. If the plan change fails after that, the answer is 502 and sending the same request again finishes it.", + "operationId": "billingUpdateSubscriptionV1", + "parameters": [ + { + "name": "subscriptionId", + "required": true, + "in": "path", + "description": "Subscription identifier", + "schema": { + "type": "string" + } + }, + { + "name": "spaceId", + "required": true, + "in": "path", + "description": "Space UUID", + "schema": { + "example": "123e4567-e89b-12d3-a456-426614174000", + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSubscriptionDto" + } + } + } + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateSubscriptionResult" + } + } + } + }, + "403": { + "description": "Not an admin, a plan this workspace is not offered, or a named paymentLinkId this workspace is not offered" + }, + "404": { + "description": "Subscription not found" + }, + "409": { + "description": "One of:\n- Already on this plan\n- The subscription is not in an updatable state\n- Several offered links sell the plan and none was named\n- The target plan doesn't offer enough Safe seats for the workspace's current Safes" + }, + "422": { + "description": "The named payment link does not offer this plan" + }, + "502": { + "description": "The billing service reported the plan change as unsuccessful, or failed after `removedSafes` were removed" + } + }, + "summary": "Move a subscription onto another plan", + "tags": [ + "billing" + ] + } + }, "/v1/billing/sessions/{sessionId}": { "get": { "operationId": "billingGetCheckoutSessionV1", @@ -1853,6 +1993,9 @@ }, "404": { "description": "Message not found" + }, + "422": { + "description": "Invalid chainId or messageHash" } }, "summary": "Get message by hash", @@ -1908,6 +2051,9 @@ }, "404": { "description": "Safe not found on the specified chain" + }, + "422": { + "description": "Invalid chainId or safeAddress" } }, "summary": "Get messages for Safe", @@ -1956,6 +2102,9 @@ }, "400": { "description": "Invalid message format or signature" + }, + "422": { + "description": "Invalid chainId, safeAddress or request body" } }, "summary": "Create message", @@ -2009,6 +2158,9 @@ }, "404": { "description": "Message not found" + }, + "422": { + "description": "Invalid chainId, messageHash or request body" } }, "summary": "Add message signature", @@ -2058,6 +2210,9 @@ }, "404": { "description": "User not found - the authenticated wallet is not associated with any user" + }, + "409": { + "description": "User is the last admin of at least one workspace - promote another admin or delete the workspace first" } }, "summary": "Delete user", @@ -2207,10 +2362,10 @@ "description": "Authentication required - valid JWT token must be provided" }, "403": { - "description": "Access forbidden - user is not a member of this space" + "description": "Access forbidden - user is not an active member of this space" }, "404": { - "description": "User, member, or space not found" + "description": "Space not found" } }, "summary": "Get space address book", @@ -2262,10 +2417,10 @@ "description": "Authentication required - valid JWT token must be provided" }, "403": { - "description": "Access forbidden - user is not authorized to modify this address book" + "description": "Access forbidden - user is not an active admin of this space" }, "404": { - "description": "User, member, or space not found" + "description": "Space not found" } }, "summary": "Update space address book", @@ -2307,10 +2462,10 @@ "description": "Invalid space identifier" }, "403": { - "description": "Access forbidden - user is not authorized to modify this address book" + "description": "Access forbidden - user is not an active admin of this space" }, "404": { - "description": "User, member, space, or address book entry not found" + "description": "Space not found" } }, "summary": "Delete address book entry", @@ -3007,6 +3162,38 @@ ] } }, + "/v1/spaces/safes": { + "get": { + "description": "Retrieves the Safes of every space the user is an active member of, one entry per space with its Safes grouped by chain like the per-space endpoint. A space without Safes has an empty `safes` object.", + "operationId": "spaceSafesGetAllV1", + "parameters": [], + "responses": { + "200": { + "description": "Safes of all spaces retrieved successfully", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/GetSpacesSafesResponse" + } + } + } + } + }, + "401": { + "description": "Authentication required" + }, + "403": { + "description": "Access forbidden - missing or invalid authentication" + } + }, + "summary": "Get Safes of all spaces", + "tags": [ + "spaces" + ] + } + }, "/v1/spaces/{spaceId}/members/invite": { "post": { "description": "Invites one or more users to join a space. Only space admins can send invitations.", @@ -3626,38 +3813,55 @@ ] } }, - "/v1/spaces/{spaceId}/surveys/{slug}/state": { + "/v1/spaces/{spaceId}/chains/{chainId}/security/{safeAddress}/recipient/{recipientAddress}": { "get": { - "description": "Returns the active survey definition and this space's response (if any) in a single round trip. Only active admins of the space can read survey state.", - "operationId": "surveysGetStateV1", + "description": "Performs real-time security analysis of a recipient address for a Safe registered to a Space, gated by the copilot_scans plan entitlement.", + "operationId": "spaceSafeShieldAnalyzeRecipientV1", "parameters": [ { - "name": "spaceId", + "name": "chainId", "required": true, "in": "path", - "description": "Space UUID to get survey state for", + "description": "Chain ID where the Safe is deployed", "schema": { - "example": "123e4567-e89b-12d3-a456-426614174000", "type": "string" } }, { - "name": "slug", + "name": "safeAddress", "required": true, "in": "path", + "description": "Safe contract address, must be registered to the Space", + "schema": { + "type": "string" + } + }, + { + "name": "recipientAddress", + "required": true, + "in": "path", + "description": "Recipient address to analyze", + "schema": { + "type": "string" + } + }, + { + "name": "spaceId", + "required": true, + "in": "path", + "description": "Space UUID", "schema": { - "example": "onboarding", "type": "string" } } ], "responses": { "200": { - "description": "", + "description": "Recipient interaction analysis results", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SurveyStateDto" + "$ref": "#/components/schemas/SingleRecipientAnalysisDto" } } } @@ -3666,90 +3870,99 @@ "description": "Invalid space identifier" }, "401": { - "description": "Not authenticated" + "description": "Authentication required" }, - "403": { - "description": "User is not an active admin of this space" + "402": { + "description": "The Space has no copilot_scans entitlement. The body carries `{ code: \"FEATURE_NOT_GRANTED\", feature }`" }, - "404": { - "description": "No active survey for this slug" + "403": { + "description": "Not a member of this Space, or the Safe is not registered to it" } }, - "summary": "Get survey state for a space", + "summary": "Analyze recipient address on a Space", "tags": [ - "surveys" + "safe-shield" ] } }, - "/v1/spaces/{spaceId}/surveys/{slug}/responses": { + "/v1/spaces/{spaceId}/chains/{chainId}/security/{safeAddress}/counterparty-analysis": { "post": { - "description": "Submits or updates the space's response to the active survey for the given slug. Only active admins of the space can submit. Idempotent: repeat submissions overwrite the previous response.", - "operationId": "surveysSubmitResponseV1", + "description": "Performs combined contract and recipient analysis for a Safe transaction on a Safe registered to a Space, gated by the copilot_scans plan entitlement.", + "operationId": "spaceSafeShieldAnalyzeCounterpartyV1", "parameters": [ { - "name": "spaceId", + "name": "chainId", "required": true, "in": "path", - "description": "Space UUID to submit a survey response for", + "description": "Chain ID where the Safe is deployed", "schema": { - "example": "123e4567-e89b-12d3-a456-426614174000", "type": "string" } }, { - "name": "slug", + "name": "safeAddress", "required": true, "in": "path", + "description": "Safe contract address, must be registered to the Space", + "schema": { + "type": "string" + } + }, + { + "name": "spaceId", + "required": true, + "in": "path", + "description": "Space UUID", "schema": { - "example": "onboarding", "type": "string" } } ], "requestBody": { "required": true, + "description": "Transaction data used to analyze all counterparties involved.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SubmitSurveyResponseDto" + "$ref": "#/components/schemas/CounterpartyAnalysisRequestDto" } } } }, "responses": { - "201": { - "description": "", + "200": { + "description": "Combined counterparty analysis including recipients and contracts grouped by status group and mapped to an address.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SurveyResponseResultDto" + "$ref": "#/components/schemas/CounterpartyAnalysisDto" } } } }, "400": { - "description": "Empty selections or unknown option keys" + "description": "Invalid space identifier" }, "401": { - "description": "Not authenticated" + "description": "Authentication required" }, - "403": { - "description": "User is not an active admin of this space" + "402": { + "description": "The Space has no copilot_scans entitlement. The body carries `{ code: \"FEATURE_NOT_GRANTED\", feature }`" }, - "404": { - "description": "No active survey for this slug" + "403": { + "description": "Not a member of this Space, or the Safe is not registered to it" } }, - "summary": "Submit a survey response for a space", + "summary": "Analyze transaction counterparties on a Space", "tags": [ - "surveys" + "safe-shield" ] } }, - "/v1/spaces/{spaceId}/entitlements": { + "/v1/spaces/{spaceId}/policies/active": { "get": { - "description": "The single source of truth for what a workspace can do: the active plan and per-feature entitlements, with quotas and usage for metered ones. Free-tier workspaces get the same contract shape.", - "operationId": "entitlementsGetEntitlementsV1", + "description": "Returns the policies of every Safe in the Space. A Safe whose spending-limit or proposer data could not be read is omitted from the corresponding policies.", + "operationId": "spacePoliciesGetActivePoliciesV1", "parameters": [ { "name": "spaceId", @@ -3760,393 +3973,436 @@ "example": "123e4567-e89b-12d3-a456-426614174000", "type": "string" } - } - ], - "responses": { - "200": { - "description": "", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/EntitlementsResponse" - } - } - } }, - "400": { - "description": "Invalid space identifier" - }, - "401": { - "description": "Authentication required" - }, - "403": { - "description": "Access forbidden - user is not a member of this space" - }, - "404": { - "description": "Space not found" - } - }, - "summary": "Get space entitlements", - "tags": [ - "entitlements" - ] - } - }, - "/v1/chains/{chainId}/owners/{ownerAddress}/safes": { - "get": { - "description": "Retrieves a list of Safe addresses that are owned by the specified address on a specific chain.", - "operationId": "ownersGetSafesByOwnerV1", - "parameters": [ { - "name": "chainId", + "name": "types", "required": true, - "in": "path", - "description": "Chain ID to search for Safes", + "in": "query", + "description": "The policy types to report, comma-separated.", "schema": { - "example": "1", - "type": "string" + "type": "array", + "items": { + "type": "string" + } } }, { - "name": "ownerAddress", - "required": true, - "in": "path", - "description": "Owner address to search Safes for (0x prefixed hex string)", + "name": "safes", + "required": false, + "in": "query", + "description": "Narrow the read to a subset of the Space's Safes, comma-separated as `{chainId}:{safeAddress}`", "schema": { + "example": "11155111:0x0000000000000000000000000000000000000000", "type": "string" } } ], "responses": { "200": { - "description": "List of Safes owned by the specified address", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SafeList" + "type": "array", + "items": { + "$ref": "#/components/schemas/ActivePolicyDto" + } } } } + }, + "400": { + "description": "Invalid space identifier" + }, + "403": { + "description": "Access forbidden - authentication missing or invalid, or user is not a member of this space" + }, + "422": { + "description": "Invalid CAIP-10 address, a Safe outside this space, or a missing or unknown policy type" + }, + "503": { + "description": "The policy api is unavailable" } }, - "summary": "Get Safes by owner", + "summary": "Get the active policies on Safes in a Space", "tags": [ - "owners" + "spaces" ] } }, - "/v2/owners/{ownerAddress}/safes": { + "/v1/spaces/{spaceId}/policies/pending": { "get": { - "description": "Retrieves all Safes owned by the specified address across all supported chains. Returns a map of chain IDs to arrays of Safe addresses.", - "operationId": "ownersGetAllSafesByOwnerV2", + "description": "Returns the spending-limit changes in the transaction queue of every Safe in the Space. Detects only direct AllowanceModule calls and calls found one level inside a MultiSend batch, and only against known AllowanceModule deployments (@safe-global/safe-modules-deployments) - a change made through a nested MultiSend, a custom batching contract, a Safe module bypassing the owner queue, or an unofficial AllowanceModule fork is not detected.", + "operationId": "spacePoliciesGetPendingPoliciesV1", "parameters": [ { - "name": "ownerAddress", + "name": "spaceId", "required": true, "in": "path", - "description": "Owner address to search Safes for (0x prefixed hex string)", + "description": "Space UUID", "schema": { + "example": "123e4567-e89b-12d3-a456-426614174000", "type": "string" } + }, + { + "name": "types", + "required": true, + "in": "query", + "description": "The policy types to report, comma-separated. Only `spending-limit` yields pending items today; other types are accepted and return none.", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } + }, + { + "name": "safes", + "required": false, + "in": "query", + "description": "Narrow the read to a subset of the Space's Safes, comma-separated as `{chainId}:{safeAddress}`", + "schema": { + "type": "array", + "items": { + "type": "string" + } + } } ], "responses": { "200": { - "description": "Map of chain IDs to arrays of Safe addresses owned by the address", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - }, - "example": { - "1": [ - "0x1234567890123456789012345678901234567890" - ], - "5": [ - "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" - ] + "type": "array", + "items": { + "$ref": "#/components/schemas/PendingPolicyDto" } } } } + }, + "400": { + "description": "Invalid space identifier" + }, + "403": { + "description": "Access forbidden - authentication missing or invalid, or user is not a member of this space" + }, + "422": { + "description": "Invalid CAIP-10 address, a Safe outside this space, or a missing or unknown policy type" + }, + "503": { + "description": "The policy api is unavailable" } }, - "summary": "Get all Safes by owner", + "summary": "Get the pending policy changes on Safes in a Space", "tags": [ - "owners" + "spaces" ] } }, - "/v3/owners/{ownerAddress}/safes": { + "/v1/spaces/{spaceId}/surveys/{slug}/state": { "get": { - "description": "Retrieves all Safes owned by the specified address across all supported chains. Returns a map of chain IDs to arrays of Safe addresses.", - "operationId": "ownersGetAllSafesByOwnerV3", + "description": "Returns the active survey definition and this space's response (if any) in a single round trip. Only active admins of the space can read survey state.", + "operationId": "surveysGetStateV1", "parameters": [ { - "name": "ownerAddress", + "name": "spaceId", + "required": true, + "in": "path", + "description": "Space UUID to get survey state for", + "schema": { + "example": "123e4567-e89b-12d3-a456-426614174000", + "type": "string" + } + }, + { + "name": "slug", "required": true, "in": "path", - "description": "Owner address to search Safes for (0x prefixed hex string)", "schema": { + "example": "onboarding", "type": "string" } } ], "responses": { "200": { - "description": "Map of chain IDs to arrays of Safe addresses owned by the address", + "description": "", "content": { "application/json": { "schema": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - }, - "example": { - "1": [ - "0x1234567890123456789012345678901234567890" - ], - "5": [ - "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" - ] - } + "$ref": "#/components/schemas/SurveyStateDto" } } } + }, + "400": { + "description": "Invalid space identifier" + }, + "401": { + "description": "Not authenticated" + }, + "403": { + "description": "User is not an active admin of this space" + }, + "404": { + "description": "No active survey for this slug" } }, - "summary": "Get all Safes by owner", + "summary": "Get survey state for a space", "tags": [ - "owners" + "surveys" ] } }, - "/v1/chains/{chainId}/relay": { + "/v1/spaces/{spaceId}/surveys/{slug}/responses": { "post": { - "description": "Relays a Safe transaction or Safe creation transaction using the relay service, which pays for gas fees. Supports execTransaction (Safe tx) and createProxyWithNonce (Safe creation) calldata. On relay-fee chains, safeTxHash is required and must match the hash derived on-chain from the submitted calldata. On chains where pre-relay Tenderly simulation is enabled, an execTransaction is simulated before being submitted: a confirmed revert returns SIMULATION_FAILED, and an unreachable simulator returns INDETERMINATE_SIMULATION (retry with acceptUnverifiedSimulation=true to proceed anyway when the simulator is unreachable).", - "operationId": "relayRelayV1", + "description": "Submits or updates the space's response to the active survey for the given slug. Only active admins of the space can submit. Idempotent: repeat submissions overwrite the previous response.", + "operationId": "surveysSubmitResponseV1", "parameters": [ { - "name": "chainId", + "name": "spaceId", "required": true, "in": "path", - "description": "Chain ID where the Safe transaction will be executed", + "description": "Space UUID to submit a survey response for", "schema": { - "example": "1", + "example": "123e4567-e89b-12d3-a456-426614174000", + "type": "string" + } + }, + { + "name": "slug", + "required": true, + "in": "path", + "schema": { + "example": "onboarding", "type": "string" } } ], "requestBody": { "required": true, - "description": "Transaction data to relay. safeTxHash is required on relay-fee chains and must correspond to the to + data fields. Set acceptUnverifiedSimulation=true to retry a relay skipping the simulation which previously returned INDETERMINATE_SIMULATION.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RelayDto" + "$ref": "#/components/schemas/SubmitSurveyResponseDto" } } } }, "responses": { - "200": { - "description": "Transaction relayed successfully", + "201": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Relay" + "$ref": "#/components/schemas/SurveyResponseResultDto" } } } }, "400": { - "description": "Request body failed schema validation" + "description": "Empty selections or unknown option keys" }, - "403": { - "description": "Relay denied: safeTxHash missing, fee service rejected, or unofficial proxy factory" + "401": { + "description": "Not authenticated" }, - "422": { - "description": "Relay rejected. The consumers MUST branch on the `code` field; `message` is informational. Possible cases: safeTxHash does not match the transaction data, unrecognised transaction type, SIMULATION_FAILED (Tenderly confirmed revert), or INDETERMINATE_SIMULATION (simulator unreachable; retry with `acceptUnverifiedSimulation=true` to proceed anyway).", - "schema": { - "examples": { - "simulationFailed": { - "summary": "SIMULATION_FAILED", - "value": { - "code": "SIMULATION_FAILED", - "message": "Relay denied: transaction simulation failed: Reverted with reason string: 'GS013'", - "statusCode": 422 - } - }, - "indeterminateSimulation": { - "summary": "INDETERMINATE_SIMULATION", - "value": { - "code": "INDETERMINATE_SIMULATION", - "message": "Relay simulation could not be completed.", - "statusCode": 422 - } - }, - "safeTxHashMismatch": { - "summary": "safeTxHash mismatch (no `code`)", - "value": { - "message": "Safe transaction hash mismatch: provided hash 0x... does not match the transaction data", - "statusCode": 422 - } - } - } - }, - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RelayErrorResponse" - } - } - } + "403": { + "description": "User is not an active admin of this space" }, - "429": { - "description": "Relay limit reached for this Safe" + "404": { + "description": "No active survey for this slug" } }, - "summary": "Relay transaction", + "summary": "Submit a survey response for a space", "tags": [ - "relay" + "surveys" ] } }, - "/v1/chains/{chainId}/relay/status/{taskId}": { + "/v1/spaces/entitlements": { "get": { - "description": "Retrieves the status of a relay task from the relay provider. This is a proxy endpoint to securely query task status without exposing the API key.", - "operationId": "relayGetTaskStatusV1", - "parameters": [ - { - "name": "chainId", - "required": true, - "in": "path", - "description": "Chain ID associated with the relay task", - "schema": { - "example": "11155111", - "type": "string" + "description": "The entitlements of every workspace the user is an active member of, keyed by workspace UUID. Each value is what the per-workspace endpoint returns.", + "operationId": "entitlementsGetAllEntitlementsV1", + "parameters": [], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "type": "object", + "additionalProperties": { + "$ref": "#/components/schemas/EntitlementsResponse" + } + } + } } }, + "401": { + "description": "Authentication required" + }, + "403": { + "description": "Access forbidden - missing or invalid authentication" + } + }, + "summary": "Get entitlements of all spaces", + "tags": [ + "entitlements" + ] + } + }, + "/v1/spaces/{spaceId}/entitlements": { + "get": { + "description": "The single source of truth for what a workspace can do: the active plan and per-feature entitlements, with quotas and usage for metered ones. Free-tier workspaces get the same contract shape.", + "operationId": "entitlementsGetEntitlementsV1", + "parameters": [ { - "name": "taskId", + "name": "spaceId", "required": true, "in": "path", - "description": "Task ID returned from the relay transaction", + "description": "Space UUID", "schema": { + "example": "123e4567-e89b-12d3-a456-426614174000", "type": "string" } } ], "responses": { "200": { - "description": "Task status retrieved successfully", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RelayTaskStatus" + "$ref": "#/components/schemas/EntitlementsResponse" } } } }, + "400": { + "description": "Invalid space identifier" + }, + "401": { + "description": "Authentication required" + }, + "403": { + "description": "Access forbidden - user is not a member of this space" + }, "404": { - "description": "Task not found" + "description": "Space not found" } }, - "summary": "Get relay task status", + "summary": "Get space entitlements", "tags": [ - "relay" + "entitlements" ] } }, - "/v1/chains/{chainId}/relay/{safeAddress}": { - "get": { - "description": "Retrieves the number of remaining relay transactions available for a specific Safe on the given chain. On relay-fee chains, safeTxHash is forwarded to the fee service to determine per-transaction eligibility (returns remaining=1 when eligible, 0 when not). On daily-limit and no-fee-campaign chains, a count-based quota is returned.", - "operationId": "relayGetRelaysRemainingV1", + "/v1/spaces/{spaceId}/chains/{chainId}/relay": { + "post": { + "description": "Relays a Safe transaction against the workspace's sponsored-transaction allowance, which its plan grants and this spends one unit of per call — a batch included. The chain must list SUBSCRIPTION among its gas payment options; no other option applies here. A call acting on an existing Safe is admitted only for a Safe the workspace holds; a Safe creation or a passkey signer deployment, having no Safe yet, is admitted as it is there.", + "operationId": "spaceRelayRelayV1", "parameters": [ { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", + "description": "Chain ID where the Safe transaction will be executed", "schema": { "example": "1", "type": "string" } }, { - "name": "safeAddress", + "name": "spaceId", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", - "schema": { - "type": "string" - } - }, - { - "name": "safeTxHash", - "required": false, - "in": "query", - "description": "Safe transaction hash (0x prefixed hex string). Required on relay-fee chains to check per-transaction eligibility with the fee service. Optional on daily-limit and no-fee-campaign chains.", + "description": "Space UUID", "schema": { + "example": "123e4567-e89b-12d3-a456-426614174000", "type": "string" } } ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SpaceRelayDto" + } + } + } + }, "responses": { - "200": { - "description": "Remaining relay quota retrieved successfully", + "201": { + "description": "Transaction relayed", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/RelaysRemaining" + "$ref": "#/components/schemas/Relay" + } + } + } + }, + "400": { + "description": "Malformed workspace identifier" + }, + "401": { + "description": "Authentication required" + }, + "402": { + "description": "The workspace's sponsored-transaction allowance is spent. The body carries `quota`, `used` and `resetsAt` so a client can offer to pay for the transaction itself." + }, + "403": { + "description": "Not a member of the workspace, or the transaction was denied" + }, + "404": { + "description": "Workspace not found" + }, + "409": { + "description": "SUBSCRIPTION cannot pay for this request: the chain does not list it or has no relayer, the Safe is not one the workspace holds, or the transaction refunds gas (`gasPrice` > 0).", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GasPaymentOptionUnavailableResponse" } } } + }, + "422": { + "description": "Request failed schema validation, or the transaction was simulated and would revert (SIMULATION_FAILED) or could not be simulated (INDETERMINATE_SIMULATION)" } }, - "summary": "Get remaining relays", + "summary": "Relay a transaction at a workspace's expense", "tags": [ "relay" ] } }, - "/v1/chains/{chainId}/safe-apps": { + "/v1/chains/{chainId}/owners/{ownerAddress}/safes": { "get": { - "description": "Retrieves a list of Safe Apps available for a specific chain, with optional filtering by client URL or app URL.", - "operationId": "safeAppsGetSafeAppsV1", + "description": "Retrieves a list of Safe addresses that are owned by the specified address on a specific chain.", + "operationId": "ownersGetSafesByOwnerV1", "parameters": [ { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID to get Safe Apps for", + "description": "Chain ID to search for Safes", "schema": { "example": "1", "type": "string" } }, { - "name": "clientUrl", - "required": false, - "in": "query", - "description": "Filter by client URL to get apps compatible with specific client", - "schema": { - "type": "string" - } - }, - { - "name": "url", - "required": false, - "in": "query", - "description": "Filter by specific Safe App URL", + "name": "ownerAddress", + "required": true, + "in": "path", + "description": "Owner address to search Safes for (0x prefixed hex string)", "schema": { "type": "string" } @@ -4154,45 +4410,32 @@ ], "responses": { "200": { - "description": "List of Safe Apps available for the specified chain", + "description": "List of Safes owned by the specified address", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SafeApp" - } + "$ref": "#/components/schemas/SafeList" } } } } }, - "summary": "Get Safe Apps", + "summary": "Get Safes by owner", "tags": [ - "safe-apps" + "owners" ] } }, - "/v1/chains/{chainId}/safes/{safeAddress}": { + "/v2/owners/{ownerAddress}/safes": { "get": { - "description": "Retrieves detailed information about a Safe including owners, threshold, modules, and current state.", - "operationId": "safesGetSafeV1", + "description": "Retrieves all Safes owned by the specified address across all supported chains. Returns a map of chain IDs to arrays of Safe addresses.", + "operationId": "ownersGetAllSafesByOwnerV2", "parameters": [ { - "name": "chainId", - "required": true, - "in": "path", - "description": "Chain ID where the Safe is deployed", - "schema": { - "example": "1", - "type": "string" - } - }, - { - "name": "safeAddress", + "name": "ownerAddress", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", + "description": "Owner address to search Safes for (0x prefixed hex string)", "schema": { "type": "string" } @@ -4200,45 +4443,46 @@ ], "responses": { "200": { - "description": "Safe information retrieved successfully", + "description": "Map of chain IDs to arrays of Safe addresses owned by the address", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SafeState" + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "example": { + "1": [ + "0x1234567890123456789012345678901234567890" + ], + "5": [ + "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" + ] + } } } } - }, - "404": { - "description": "Safe not found on the specified chain" } }, - "summary": "Get Safe information", + "summary": "Get all Safes by owner", "tags": [ - "safes" + "owners" ] } }, - "/v1/chains/{chainId}/safes/{safeAddress}/nonces": { + "/v3/owners/{ownerAddress}/safes": { "get": { - "description": "Retrieves the current nonces for a Safe, including the transaction nonce and any queued nonces.", - "operationId": "safesGetNoncesV1", + "description": "Retrieves all Safes owned by the specified address across all supported chains. Returns a map of chain IDs to arrays of Safe addresses.", + "operationId": "ownersGetAllSafesByOwnerV3", "parameters": [ { - "name": "chainId", - "required": true, - "in": "path", - "description": "Chain ID where the Safe is deployed", - "schema": { - "example": "1", - "type": "string" - } - }, - { - "name": "safeAddress", + "name": "ownerAddress", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", + "description": "Owner address to search Safes for (0x prefixed hex string)", "schema": { "type": "string" } @@ -4246,75 +4490,157 @@ ], "responses": { "200": { - "description": "Safe nonces retrieved successfully", + "description": "Map of chain IDs to arrays of Safe addresses owned by the address", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SafeNonces" + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "example": { + "1": [ + "0x1234567890123456789012345678901234567890" + ], + "5": [ + "0xabcdefabcdefabcdefabcdefabcdefabcdefabcd" + ] + } } } } - }, - "404": { - "description": "Safe not found on the specified chain" } }, - "summary": "Get Safe nonces", + "summary": "Get all Safes by owner", "tags": [ - "safes" + "owners" ] } }, - "/v1/safes": { - "get": { - "description": "Retrieves an overview of multiple Safes including their balances, transaction counts, and other summary information. Supports cross-chain queries using CAIP-10 address format.", - "operationId": "safesGetSafeOverviewV1", + "/v1/chains/{chainId}/relay": { + "post": { + "description": "Relays a Safe transaction or Safe creation transaction using the relay service, which pays for gas fees. Supports execTransaction (Safe tx) and createProxyWithNonce (Safe creation) calldata. On relay-fee chains, safeTxHash is required and must match the hash derived on-chain from the submitted calldata. On chains where pre-relay Tenderly simulation is enabled, an execTransaction is simulated before being submitted: a confirmed revert returns SIMULATION_FAILED, and an unreachable simulator returns INDETERMINATE_SIMULATION (retry with acceptUnverifiedSimulation=true to proceed anyway when the simulator is unreachable).", + "operationId": "relayRelayV1", "parameters": [ { - "name": "currency", + "name": "chainId", "required": true, - "in": "query", - "description": "Fiat currency code for balance conversion (e.g., USD, EUR)", + "in": "path", + "description": "Chain ID where the Safe transaction will be executed", "schema": { - "example": "USD", + "example": "1", "type": "string" } - }, - { - "name": "safes", - "required": true, - "in": "query", - "description": "Comma-separated list of Safe addresses in CAIP-10 format (chainId:address)", - "schema": { - "example": "1:0x1234567890123456789012345678901234567890,5:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", - "type": "string" + } + ], + "requestBody": { + "required": true, + "description": "Transaction data to relay. safeTxHash is required on relay-fee chains and must correspond to the to + data fields. Set acceptUnverifiedSimulation=true to retry a relay skipping the simulation which previously returned INDETERMINATE_SIMULATION.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RelayDto" + } + } + } + }, + "responses": { + "200": { + "description": "Transaction relayed successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/Relay" + } + } } }, - { - "name": "trusted", - "required": false, - "in": "query", - "description": "If true, only includes trusted tokens in balance calculations", + "400": { + "description": "Request body failed schema validation" + }, + "403": { + "description": "Relay denied: safeTxHash missing, fee service rejected, or unofficial proxy factory" + }, + "409": { + "description": "A transaction that refunds gas (`gasPrice` > 0) needs PAY_FROM_SAFE, which the chain does not offer.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GasPaymentOptionUnavailableResponse" + } + } + } + }, + "422": { + "description": "Relay rejected. The consumers MUST branch on the `code` field; `message` is informational. Possible cases: safeTxHash does not match the transaction data, unrecognised transaction type, SIMULATION_FAILED (Tenderly confirmed revert), or INDETERMINATE_SIMULATION (simulator unreachable; retry with `acceptUnverifiedSimulation=true` to proceed anyway).", "schema": { - "example": false, - "type": "boolean" + "examples": { + "simulationFailed": { + "summary": "SIMULATION_FAILED", + "value": { + "code": "SIMULATION_FAILED", + "message": "Relay denied: transaction simulation failed: Reverted with reason string: 'GS013'", + "statusCode": 422 + } + }, + "indeterminateSimulation": { + "summary": "INDETERMINATE_SIMULATION", + "value": { + "code": "INDETERMINATE_SIMULATION", + "message": "Relay simulation could not be completed.", + "statusCode": 422 + } + }, + "safeTxHashMismatch": { + "summary": "safeTxHash mismatch (no `code`)", + "value": { + "message": "Safe transaction hash mismatch: provided hash 0x... does not match the transaction data", + "statusCode": 422 + } + } + } + }, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RelayErrorResponse" + } + } } }, + "429": { + "description": "Relay limit reached for this Safe" + } + }, + "summary": "Relay transaction", + "tags": [ + "relay" + ] + } + }, + "/v1/chains/{chainId}/relay/status/{taskId}": { + "get": { + "description": "Retrieves the status of a relay task from the relay provider. This is a proxy endpoint to securely query task status without exposing the API key.", + "operationId": "relayGetTaskStatusV1", + "parameters": [ { - "name": "exclude_spam", - "required": false, - "in": "query", - "description": "If true, excludes spam tokens from balance calculations", + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID associated with the relay task", "schema": { - "example": true, - "type": "boolean" + "example": "11155111", + "type": "string" } }, { - "name": "wallet_address", - "required": false, - "in": "query", - "description": "Optional wallet address to filter Safes where this address is an owner", + "name": "taskId", + "required": true, + "in": "path", + "description": "Task ID returned from the relay transaction", "schema": { "type": "string" } @@ -4322,65 +4648,54 @@ ], "responses": { "200": { - "description": "Array of Safe overviews with balances and metadata", + "description": "Task status retrieved successfully", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SafeOverview" - } + "$ref": "#/components/schemas/RelayTaskStatus" } } } + }, + "404": { + "description": "Task not found" } }, - "summary": "Get Safe overview", + "summary": "Get relay task status", "tags": [ - "safes" + "relay" ] } }, - "/v2/safes": { + "/v1/chains/{chainId}/relay/{safeAddress}": { "get": { - "description": "Retrieves an overview of multiple Safes. Supports cross-chain queries using chainId:address format.", - "operationId": "safesGetSafeOverviewV2", + "description": "Retrieves the free relays left for a specific Safe on the given chain: the no-fee campaign quota where the chain lists NO_FEE_CAMPAIGN, otherwise the daily limit where it lists FREE_DAILY_LIMIT.", + "operationId": "relayGetRelaysRemainingV1", "parameters": [ { - "name": "currency", + "name": "chainId", "required": true, - "in": "query", - "description": "Fiat currency code for balance conversion (e.g., USD, EUR)", + "in": "path", + "description": "Chain ID where the Safe is deployed", "schema": { - "example": "USD", + "example": "1", "type": "string" } }, { - "name": "safes", + "name": "safeAddress", "required": true, - "in": "query", - "description": "Comma-separated list of Safe addresses in chainId:address format", + "in": "path", + "description": "Safe contract address (0x prefixed hex string)", "schema": { - "example": "1:0x1234567890123456789012345678901234567890,5:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", "type": "string" } }, { - "name": "trusted", - "required": false, - "in": "query", - "description": "If true, only includes trusted tokens in balance calculations.", - "schema": { - "example": false, - "type": "boolean" - } - }, - { - "name": "wallet_address", + "name": "safeTxHash", "required": false, "in": "query", - "description": "Optional wallet address to filter Safes where this address is an owner", + "description": "Safe transaction hash (0x prefixed hex string). Ignored; kept so existing clients do not break.", "schema": { "type": "string" } @@ -4388,54 +4703,54 @@ ], "responses": { "200": { - "description": "Array of Safe overviews with balances and metadata", + "description": "Remaining relay quota retrieved successfully", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SafeOverview" - } + "$ref": "#/components/schemas/RelaysRemaining" } } } + }, + "403": { + "description": "The chain has no relayer or lists no free option, such as a chain that only lists PAY_FROM_SAFE" } }, - "summary": "Get Safe overview (v2)", + "summary": "Get remaining relays", "tags": [ - "safes" + "relay" ] } }, - "/v1/chains/{chainId}/security/{safeAddress}/recipient/{recipientAddress}": { + "/v1/chains/{chainId}/safe-apps": { "get": { - "description": "Performs real-time security analysis of a recipient address for a specific Safe. Returns analysis results grouped by status group, sorted by severity (CRITICAL first).", - "operationId": "safeShieldAnalyzeRecipientV1", + "description": "Retrieves a list of Safe Apps available for a specific chain, with optional filtering by client URL or app URL.", + "operationId": "safeAppsGetSafeAppsV1", "parameters": [ { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", + "description": "Chain ID to get Safe Apps for", "schema": { "example": "1", "type": "string" } }, { - "name": "safeAddress", - "required": true, - "in": "path", - "description": "Safe contract address", + "name": "clientUrl", + "required": false, + "in": "query", + "description": "Filter by client URL to get apps compatible with specific client", "schema": { "type": "string" } }, { - "name": "recipientAddress", - "required": true, - "in": "path", - "description": "Recipient address to analyze", + "name": "url", + "required": false, + "in": "query", + "description": "Filter by specific Safe App URL", "schema": { "type": "string" } @@ -4443,26 +4758,29 @@ ], "responses": { "200": { - "description": "Recipient interaction analysis results", + "description": "List of Safe Apps available for the specified chain", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/SingleRecipientAnalysisDto" + "type": "array", + "items": { + "$ref": "#/components/schemas/SafeApp" + } } } } } }, - "summary": "Analyze recipient address", + "summary": "Get Safe Apps", "tags": [ - "safe-shield" + "safe-apps" ] } }, - "/v1/chains/{chainId}/security/{safeAddress}/counterparty-analysis": { - "post": { - "description": "Performs combined contract and recipient analysis for a Safe transaction. Returns both analyses grouped by status group for each counterparty.", - "operationId": "safeShieldAnalyzeCounterpartyV1", + "/v1/chains/{chainId}/safes/{safeAddress}": { + "get": { + "description": "Retrieves detailed information about a Safe including owners, threshold, modules, and current state.", + "operationId": "safesGetSafeV1", "parameters": [ { "name": "chainId", @@ -4478,45 +4796,37 @@ "name": "safeAddress", "required": true, "in": "path", - "description": "Safe contract address", + "description": "Safe contract address (0x prefixed hex string)", "schema": { "type": "string" } } ], - "requestBody": { - "required": true, - "description": "Transaction data used to analyze all counterparties involved.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/CounterpartyAnalysisRequestDto" - } - } - } - }, "responses": { "200": { - "description": "Combined counterparty analysis including recipients and contracts grouped by status group and mapped to an address.", + "description": "Safe information retrieved successfully", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CounterpartyAnalysisDto" + "$ref": "#/components/schemas/SafeState" } } } + }, + "404": { + "description": "Safe not found on the specified chain" } }, - "summary": "Analyze transaction counterparties", + "summary": "Get Safe information", "tags": [ - "safe-shield" + "safes" ] } }, - "/v1/chains/{chainId}/security/{safeAddress}/threat-analysis": { - "post": { - "description": "Performs real-time threat analysis for a Safe transaction.", - "operationId": "safeShieldAnalyzeThreatV1", + "/v1/chains/{chainId}/safes/{safeAddress}/nonces": { + "get": { + "description": "Retrieves the current nonces for a Safe, including the transaction nonce and any queued nonces.", + "operationId": "safesGetNoncesV1", "parameters": [ { "name": "chainId", @@ -4524,6 +4834,7 @@ "in": "path", "description": "Chain ID where the Safe is deployed", "schema": { + "example": "1", "type": "string" } }, @@ -4531,119 +4842,149 @@ "name": "safeAddress", "required": true, "in": "path", - "description": "Safe contract address", + "description": "Safe contract address (0x prefixed hex string)", "schema": { "type": "string" } } ], - "requestBody": { - "required": true, - "description": "EIP-712 typed data and wallet information for threat analysis.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ThreatAnalysisRequestDto" - } - } - } - }, "responses": { "200": { - "description": "Threat analysis results including threat findings and balance changes.", + "description": "Safe nonces retrieved successfully", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ThreatAnalysisResponseDto" + "$ref": "#/components/schemas/SafeNonces" } } } + }, + "404": { + "description": "Safe not found on the specified chain" } }, - "summary": "Analyze transaction threat", + "summary": "Get Safe nonces", "tags": [ - "safe-shield" + "safes" ] } }, - "/v1/chains/{chainId}/security/{safeAddress}/report-false-result": { - "post": { - "description": "Reports a FALSE_POSITIVE or FALSE_NEGATIVE Blockaid transaction scan result for review. Use the request_id from the original scan response to identify the transaction.", - "operationId": "safeShieldReportFalseResultV1", + "/v1/safes": { + "get": { + "description": "Retrieves an overview of multiple Safes including their balances, transaction counts, and other summary information. Supports cross-chain queries using CAIP-10 address format.", + "operationId": "safesGetSafeOverviewV1", "parameters": [ { - "name": "chainId", + "name": "currency", "required": true, - "in": "path", - "description": "Chain ID where the Safe is deployed", + "in": "query", + "description": "Fiat currency code for balance conversion (e.g., USD, EUR)", "schema": { - "example": "1", + "example": "USD", "type": "string" } }, { - "name": "safeAddress", + "name": "safes", "required": true, - "in": "path", - "description": "Safe contract address", + "in": "query", + "description": "Comma-separated list of Safe addresses in CAIP-10 format (chainId:address)", "schema": { + "example": "1:0x1234567890123456789012345678901234567890,5:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", "type": "string" } - } - ], - "requestBody": { - "required": true, - "description": "Report details including event type, request_id from scan response, and details.", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/ReportFalseResultRequestDto" - } + }, + { + "name": "trusted", + "required": false, + "in": "query", + "description": "If true, only includes trusted tokens in balance calculations", + "schema": { + "example": false, + "type": "boolean" + } + }, + { + "name": "exclude_spam", + "required": false, + "in": "query", + "description": "If true, excludes spam tokens from balance calculations", + "schema": { + "example": true, + "type": "boolean" + } + }, + { + "name": "wallet_address", + "required": false, + "in": "query", + "description": "Optional wallet address to filter Safes where this address is an owner", + "schema": { + "type": "string" } } - }, + ], "responses": { "200": { - "description": "Report submitted successfully.", + "description": "Array of Safe overviews with balances and metadata", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ReportFalseResultResponseDto" + "type": "array", + "items": { + "$ref": "#/components/schemas/SafeOverview" + } } } } } }, - "summary": "Report false Blockaid scan result", + "summary": "Get Safe overview", "tags": [ - "safe-shield" + "safes" ] } }, - "/v1/targeted-messaging/outreaches/{outreachId}/chains/{chainId}/safes/{safeAddress}": { + "/v2/safes": { "get": { - "operationId": "targetedMessagingGetTargetedSafeV1", + "description": "Retrieves an overview of multiple Safes. Supports cross-chain queries using chainId:address format.", + "operationId": "safesGetSafeOverviewV2", "parameters": [ { - "name": "outreachId", + "name": "currency", "required": true, - "in": "path", + "in": "query", + "description": "Fiat currency code for balance conversion (e.g., USD, EUR)", "schema": { - "type": "number" + "example": "USD", + "type": "string" } }, { - "name": "chainId", + "name": "safes", "required": true, - "in": "path", + "in": "query", + "description": "Comma-separated list of Safe addresses in chainId:address format", "schema": { + "example": "1:0x1234567890123456789012345678901234567890,5:0xabcdefabcdefabcdefabcdefabcdefabcdefabcd", "type": "string" } }, { - "name": "safeAddress", - "required": true, - "in": "path", + "name": "trusted", + "required": false, + "in": "query", + "description": "If true, only includes trusted tokens in balance calculations.", + "schema": { + "example": false, + "type": "boolean" + } + }, + { + "name": "wallet_address", + "required": false, + "in": "query", + "description": "Optional wallet address to filter Safes where this address is an owner", "schema": { "type": "string" } @@ -4651,41 +4992,37 @@ ], "responses": { "200": { - "description": "", + "description": "Array of Safe overviews with balances and metadata", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TargetedSafe" + "type": "array", + "items": { + "$ref": "#/components/schemas/SafeOverview" + } } } } - }, - "404": { - "description": "Safe not targeted." } }, + "summary": "Get Safe overview (v2)", "tags": [ - "targeted-messaging" + "safes" ] } }, - "/v1/targeted-messaging/outreaches/{outreachId}/chains/{chainId}/safes/{safeAddress}/signers/{signerAddress}/submissions": { + "/v1/chains/{chainId}/security/{safeAddress}/recipient/{recipientAddress}": { "get": { - "operationId": "targetedMessagingGetSubmissionV1", + "description": "Performs real-time security analysis of a recipient address for a specific Safe. Returns analysis results grouped by status group, sorted by severity (CRITICAL first).", + "operationId": "safeShieldAnalyzeRecipientV1", "parameters": [ - { - "name": "outreachId", - "required": true, - "in": "path", - "schema": { - "type": "number" - } - }, { "name": "chainId", "required": true, "in": "path", + "description": "Chain ID where the Safe is deployed", "schema": { + "example": "1", "type": "string" } }, @@ -4693,14 +5030,16 @@ "name": "safeAddress", "required": true, "in": "path", + "description": "Safe contract address", "schema": { "type": "string" } }, { - "name": "signerAddress", + "name": "recipientAddress", "required": true, "in": "path", + "description": "Recipient address to analyze", "schema": { "type": "string" } @@ -4708,36 +5047,37 @@ ], "responses": { "200": { - "description": "", + "description": "Recipient interaction analysis results", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Submission" + "$ref": "#/components/schemas/SingleRecipientAnalysisDto" } } } + }, + "402": { + "description": "Disabled on Core. The body carries `{ code: \"SAFE_SHIELD_DISABLED_ON_CORE\", message }`." } }, + "summary": "Analyze recipient address", "tags": [ - "targeted-messaging" + "safe-shield" ] - }, + } + }, + "/v1/chains/{chainId}/security/{safeAddress}/counterparty-analysis": { "post": { - "operationId": "targetedMessagingCreateSubmissionV1", + "description": "Performs combined contract and recipient analysis for a Safe transaction. Returns both analyses grouped by status group for each counterparty.", + "operationId": "safeShieldAnalyzeCounterpartyV1", "parameters": [ - { - "name": "outreachId", - "required": true, - "in": "path", - "schema": { - "type": "number" - } - }, { "name": "chainId", "required": true, "in": "path", + "description": "Chain ID where the Safe is deployed", "schema": { + "example": "1", "type": "string" } }, @@ -4745,14 +5085,7 @@ "name": "safeAddress", "required": true, "in": "path", - "schema": { - "type": "string" - } - }, - { - "name": "signerAddress", - "required": true, - "in": "path", + "description": "Safe contract address", "schema": { "type": "string" } @@ -4760,83 +5093,91 @@ ], "requestBody": { "required": true, + "description": "Transaction data used to analyze all counterparties involved.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/CreateSubmissionDto" + "$ref": "#/components/schemas/CounterpartyAnalysisRequestDto" } } } }, "responses": { - "201": { - "description": "", + "200": { + "description": "Combined counterparty analysis including recipients and contracts grouped by status group and mapped to an address.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Submission" + "$ref": "#/components/schemas/CounterpartyAnalysisDto" } } } } }, + "summary": "Analyze transaction counterparties", "tags": [ - "targeted-messaging" + "safe-shield" ] } }, - "/v1/chains/{chainId}/transactions/{id}": { - "get": { - "description": "Retrieves detailed information about a specific transaction by its ID, including execution status, confirmations, and decoded transaction data.", - "operationId": "transactionsGetTransactionByIdV1", + "/v1/chains/{chainId}/security/{safeAddress}/threat-analysis": { + "post": { + "description": "Performs real-time threat analysis for a Safe transaction.", + "operationId": "safeShieldAnalyzeThreatV1", "parameters": [ { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the transaction exists", + "description": "Chain ID where the Safe is deployed", "schema": { - "example": "1", "type": "string" } }, { - "name": "id", + "name": "safeAddress", "required": true, "in": "path", - "description": "Transaction ID (safe transaction hash or multisig transaction ID)", + "description": "Safe contract address", "schema": { - "example": "multisig_0x1234567890123456789012345678901234567890_0x5678...", "type": "string" } } ], + "requestBody": { + "required": true, + "description": "EIP-712 typed data and wallet information for threat analysis.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ThreatAnalysisRequestDto" + } + } + } + }, "responses": { "200": { - "description": "Transaction details retrieved successfully", + "description": "Threat analysis results including threat findings and balance changes.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TransactionDetails" + "$ref": "#/components/schemas/ThreatAnalysisResponseDto" } } } - }, - "404": { - "description": "Transaction not found" } }, - "summary": "Get transaction details", + "summary": "Analyze transaction threat", "tags": [ - "transactions" + "safe-shield" ] } }, - "/v1/chains/{chainId}/safes/{safeAddress}/multisig-transactions": { - "get": { - "description": "Retrieves a paginated list of multisig transactions for a Safe with optional filtering by execution date, recipient, value, nonce, and execution status.", - "operationId": "transactionsGetMultisigTransactionsV1", - "parameters": [ + "/v1/chains/{chainId}/security/{safeAddress}/report-false-result": { + "post": { + "description": "Reports a FALSE_POSITIVE or FALSE_NEGATIVE Blockaid transaction scan result for review. Use the request_id from the original scan response to identify the transaction.", + "operationId": "safeShieldReportFalseResultV1", + "parameters": [ { "name": "chainId", "required": true, @@ -4851,202 +5192,122 @@ "name": "safeAddress", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", - "schema": { - "type": "string" - } - }, - { - "name": "execution_date__gte", - "required": false, - "in": "query", - "description": "Filter by execution date greater than or equal to (ISO 8601 format)", - "schema": { - "type": "string" - } - }, - { - "name": "execution_date__lte", - "required": false, - "in": "query", - "description": "Filter by execution date less than or equal to (ISO 8601 format)", - "schema": { - "type": "string" - } - }, - { - "name": "to", - "required": false, - "in": "query", - "description": "Filter by recipient address (0x prefixed hex string)", - "schema": { - "type": "string" - } - }, - { - "name": "value", - "required": false, - "in": "query", - "description": "Filter by transaction value in wei", - "schema": { - "type": "string" - } - }, - { - "name": "nonce", - "required": false, - "in": "query", - "description": "Filter by transaction nonce", - "schema": { - "type": "string" - } - }, - { - "name": "executed", - "required": false, - "in": "query", - "description": "Filter by execution status (true for executed, false for pending)", - "schema": { - "type": "boolean" - } - }, - { - "name": "cursor", - "required": false, - "in": "query", - "description": "Pagination cursor for retrieving the next set of results", + "description": "Safe contract address", "schema": { "type": "string" } } ], + "requestBody": { + "required": true, + "description": "Report details including event type, request_id from scan response, and details.", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReportFalseResultRequestDto" + } + } + } + }, "responses": { "200": { - "description": "Paginated list of multisig transactions", + "description": "Report submitted successfully.", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/MultisigTransactionPage" + "$ref": "#/components/schemas/ReportFalseResultResponseDto" } } } } }, - "summary": "Get multisig transactions", + "summary": "Report false Blockaid scan result", "tags": [ - "transactions" + "safe-shield" ] } }, - "/v1/chains/{chainId}/transactions/{safeTxHash}": { - "delete": { - "description": "Deletes a pending multisig transaction. Only the proposer or a Safe owner can delete a transaction.", - "operationId": "transactionsDeleteTransactionV1", + "/v1/targeted-messaging/outreaches/{outreachId}/chains/{chainId}/safes/{safeAddress}": { + "get": { + "operationId": "targetedMessagingGetTargetedSafeV1", "parameters": [ + { + "name": "outreachId", + "required": true, + "in": "path", + "schema": { + "type": "number" + } + }, { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the transaction exists", "schema": { - "example": "1", "type": "string" } }, { - "name": "safeTxHash", + "name": "safeAddress", "required": true, "in": "path", - "description": "Safe transaction hash (0x prefixed hex string)", "schema": { "type": "string" } } ], - "requestBody": { - "required": true, - "description": "Signature proving authorization to delete the transaction", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/DeleteTransactionDto" + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TargetedSafe" + } } } - } - }, - "responses": { - "204": { - "description": "Transaction deleted successfully" - }, - "400": { - "description": "Invalid signature or unauthorized deletion attempt" }, "404": { - "description": "Transaction not found" + "description": "Safe not targeted." } }, - "summary": "Delete transaction", "tags": [ - "transactions" + "targeted-messaging" ] } }, - "/v1/chains/{chainId}/safes/{safeAddress}/module-transactions": { + "/v1/targeted-messaging/outreaches/{outreachId}/chains/{chainId}/safes/{safeAddress}/signers/{signerAddress}/submissions": { "get": { - "description": "Retrieves a paginated list of module transactions for a Safe. Module transactions are executed directly by enabled modules without requiring owner signatures.", - "operationId": "transactionsGetModuleTransactionsV1", + "operationId": "targetedMessagingGetSubmissionV1", "parameters": [ { - "name": "chainId", + "name": "outreachId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", "schema": { - "example": "1", - "type": "string" + "type": "number" } }, { - "name": "safeAddress", + "name": "chainId", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", - "schema": { - "type": "string" - } - }, - { - "name": "to", - "required": false, - "in": "query", - "description": "Filter by recipient address (0x prefixed hex string)", "schema": { "type": "string" } }, { - "name": "module", - "required": false, - "in": "query", - "description": "Filter by module address that executed the transaction", - "schema": { - "type": "string" - } - }, - { - "name": "transaction_hash", - "required": false, - "in": "query", - "description": "Filter by specific transaction hash", + "name": "safeAddress", + "required": true, + "in": "path", "schema": { "type": "string" } }, { - "name": "cursor", - "required": false, - "in": "query", - "description": "Pagination cursor for retrieving the next set of results", + "name": "signerAddress", + "required": true, + "in": "path", "schema": { "type": "string" } @@ -5054,42 +5315,51 @@ ], "responses": { "200": { - "description": "Paginated list of module transactions", + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/ModuleTransactionPage" + "$ref": "#/components/schemas/Submission" } } } } }, - "summary": "Get module transactions", "tags": [ - "transactions" + "targeted-messaging" ] - } - }, - "/v1/chains/{chainId}/transactions/{safeTxHash}/confirmations": { + }, "post": { - "description": "Adds a confirmation signature to a pending multisig transaction. Once enough confirmations are collected to meet the Safe threshold, the transaction can be executed.", - "operationId": "transactionsAddConfirmationV1", + "operationId": "targetedMessagingCreateSubmissionV1", "parameters": [ + { + "name": "outreachId", + "required": true, + "in": "path", + "schema": { + "type": "number" + } + }, { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", "schema": { - "example": "1", "type": "string" } }, { - "name": "safeTxHash", + "name": "safeAddress", + "required": true, + "in": "path", + "schema": { + "type": "string" + } + }, + { + "name": "signerAddress", "required": true, "in": "path", - "description": "Safe transaction hash (0x prefixed hex string)", "schema": { "type": "string" } @@ -5097,70 +5367,100 @@ ], "requestBody": { "required": true, - "description": "Confirmation signature from a Safe owner proving their approval of the transaction", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/AddConfirmationDto" + "$ref": "#/components/schemas/CreateSubmissionDto" } } } }, "responses": { - "200": { - "description": "Transaction details with updated confirmation status", + "201": { + "description": "", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/Transaction" + "$ref": "#/components/schemas/Submission" } } } - }, - "400": { - "description": "Invalid signature or confirmation already exists for this owner" - }, - "404": { - "description": "Transaction not found" } }, - "summary": "Add transaction confirmation", "tags": [ - "transactions" + "targeted-messaging" ] } }, - "/v1/chains/{chainId}/safes/{safeAddress}/incoming-transfers": { + "/v1/chains/{chainId}/transactions/{id}": { "get": { - "description": "Retrieves a paginated list of incoming transfers to a Safe, including ETH and token transfers with optional filtering by date, value, token, and trust status.", - "operationId": "transactionsGetIncomingTransfersV1", + "description": "Retrieves detailed information about a specific transaction by its ID, including execution status, confirmations, and decoded transaction data.", + "operationId": "transactionsGetTransactionByIdV1", "parameters": [ { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", + "description": "Chain ID where the transaction exists", "schema": { "example": "1", "type": "string" } }, { - "name": "safeAddress", + "name": "id", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", + "description": "Transaction ID (safe transaction hash or multisig transaction ID)", "schema": { + "example": "multisig_0x1234567890123456789012345678901234567890_0x5678...", "type": "string" } - }, - { - "name": "trusted", - "required": false, - "in": "query", - "description": "Filter by trust status (true for trusted tokens, false for untrusted)", - "schema": { - "type": "boolean" + } + ], + "responses": { + "200": { + "description": "Transaction details retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransactionDetails" + } + } + } + }, + "404": { + "description": "Transaction not found" + } + }, + "summary": "Get transaction details", + "tags": [ + "transactions" + ] + } + }, + "/v1/chains/{chainId}/safes/{safeAddress}/multisig-transactions": { + "get": { + "description": "Retrieves a paginated list of multisig transactions for a Safe with optional filtering by execution date, recipient, value, nonce, and execution status.", + "operationId": "transactionsGetMultisigTransactionsV1", + "parameters": [ + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where the Safe is deployed", + "schema": { + "example": "1", + "type": "string" + } + }, + { + "name": "safeAddress", + "required": true, + "in": "path", + "description": "Safe contract address (0x prefixed hex string)", + "schema": { + "type": "string" } }, { @@ -5194,20 +5494,29 @@ "name": "value", "required": false, "in": "query", - "description": "Filter by transfer value in wei", + "description": "Filter by transaction value in wei", "schema": { "type": "string" } }, { - "name": "token_address", + "name": "nonce", "required": false, "in": "query", - "description": "Filter by token contract address (0x prefixed hex string for ERC-20 tokens)", + "description": "Filter by transaction nonce", "schema": { "type": "string" } }, + { + "name": "executed", + "required": false, + "in": "query", + "description": "Filter by execution status (true for executed, false for pending)", + "schema": { + "type": "boolean" + } + }, { "name": "cursor", "required": false, @@ -5220,42 +5529,42 @@ ], "responses": { "200": { - "description": "Paginated list of incoming transfers", + "description": "Paginated list of multisig transactions", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/IncomingTransferPage" + "$ref": "#/components/schemas/MultisigTransactionPage" } } } } }, - "summary": "Get incoming transfers", + "summary": "Get multisig transactions", "tags": [ "transactions" ] } }, - "/v1/chains/{chainId}/transactions/{safeAddress}/preview": { - "post": { - "description": "Simulates a transaction execution to preview its effects, including gas estimates, balance changes, and potential errors before actually proposing or executing it.", - "operationId": "transactionsPreviewTransactionV1", + "/v1/chains/{chainId}/transactions/{safeTxHash}": { + "delete": { + "description": "Deletes a pending multisig transaction. Only the proposer or a Safe owner can delete a transaction.", + "operationId": "transactionsDeleteTransactionV1", "parameters": [ { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", + "description": "Chain ID where the transaction exists", "schema": { "example": "1", "type": "string" } }, { - "name": "safeAddress", + "name": "safeTxHash", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", + "description": "Safe transaction hash (0x prefixed hex string)", "schema": { "type": "string" } @@ -5263,43 +5572,36 @@ ], "requestBody": { "required": true, - "description": "Transaction data to preview including recipient, value, data, and operation type", + "description": "Signature proving authorization to delete the transaction", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/PreviewTransactionDto" + "$ref": "#/components/schemas/DeleteTransactionDto" } } } }, "responses": { - "200": { - "description": "Transaction preview with simulation results, gas estimates, and potential effects", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/TransactionPreview" - } - } - } + "204": { + "description": "Transaction deleted successfully" }, "400": { - "description": "Invalid transaction data or simulation failed" + "description": "Invalid signature or unauthorized deletion attempt" }, "404": { - "description": "Safe not found" + "description": "Transaction not found" } }, - "summary": "Preview transaction", + "summary": "Delete transaction", "tags": [ "transactions" ] } }, - "/v1/chains/{chainId}/safes/{safeAddress}/transactions/queued": { + "/v1/chains/{chainId}/safes/{safeAddress}/module-transactions": { "get": { - "description": "Retrieves a paginated list of queued (pending) transactions for a Safe that are waiting for execution, ordered by nonce.", - "operationId": "transactionsGetTransactionQueueV1", + "description": "Retrieves a paginated list of module transactions for a Safe. Module transactions are executed directly by enabled modules without requiring owner signatures.", + "operationId": "transactionsGetModuleTransactionsV1", "parameters": [ { "name": "chainId", @@ -5321,12 +5623,30 @@ } }, { - "name": "trusted", + "name": "to", "required": false, "in": "query", - "description": "Filter by trust status (true for trusted transactions, false for untrusted)", + "description": "Filter by recipient address (0x prefixed hex string)", "schema": { - "type": "boolean" + "type": "string" + } + }, + { + "name": "module", + "required": false, + "in": "query", + "description": "Filter by module address that executed the transaction", + "schema": { + "type": "string" + } + }, + { + "name": "transaction_hash", + "required": false, + "in": "query", + "description": "Filter by specific transaction hash", + "schema": { + "type": "string" } }, { @@ -5341,26 +5661,86 @@ ], "responses": { "200": { - "description": "Paginated list of queued transactions", + "description": "Paginated list of module transactions", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/QueuedItemPage" + "$ref": "#/components/schemas/ModuleTransactionPage" } } } } }, - "summary": "Get transaction queue", + "summary": "Get module transactions", "tags": [ "transactions" ] } }, - "/v1/chains/{chainId}/safes/{safeAddress}/transactions/history": { + "/v1/chains/{chainId}/transactions/{safeTxHash}/confirmations": { + "post": { + "description": "Adds a confirmation signature to a pending multisig transaction. Once enough confirmations are collected to meet the Safe threshold, the transaction can be executed.", + "operationId": "transactionsAddConfirmationV1", + "parameters": [ + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where the Safe is deployed", + "schema": { + "example": "1", + "type": "string" + } + }, + { + "name": "safeTxHash", + "required": true, + "in": "path", + "description": "Safe transaction hash (0x prefixed hex string)", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "description": "Confirmation signature from a Safe owner proving their approval of the transaction", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AddConfirmationDto" + } + } + } + }, + "responses": { + "200": { + "description": "Transaction details with updated confirmation status", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransactionDetails" + } + } + } + }, + "400": { + "description": "Invalid signature or confirmation already exists for this owner" + }, + "404": { + "description": "Transaction not found" + } + }, + "summary": "Add transaction confirmation", + "tags": [ + "transactions" + ] + } + }, + "/v1/chains/{chainId}/safes/{safeAddress}/incoming-transfers": { "get": { - "description": "Retrieves a paginated list of executed transactions for a Safe, including multisig transactions, module transactions, and incoming transfers, ordered by execution date.", - "operationId": "transactionsGetTransactionsHistoryV1", + "description": "Retrieves a paginated list of incoming transfers to a Safe, including ETH and token transfers with optional filtering by date, value, token, and trust status.", + "operationId": "transactionsGetIncomingTransfersV1", "parameters": [ { "name": "chainId", @@ -5382,38 +5762,55 @@ } }, { - "name": "timezone_offset", + "name": "trusted", "required": false, "in": "query", - "deprecated": true, - "description": "Deprecated: Timezone offset in milliseconds for date formatting (use timezone parameter instead)", + "description": "Filter by trust status (true for trusted tokens, false for untrusted)", + "schema": { + "type": "boolean" + } + }, + { + "name": "execution_date__gte", + "required": false, + "in": "query", + "description": "Filter by execution date greater than or equal to (ISO 8601 format)", "schema": { "type": "string" } }, { - "name": "trusted", + "name": "execution_date__lte", "required": false, "in": "query", - "description": "Filter by trust status (default: true, set to false to include untrusted transactions)", + "description": "Filter by execution date less than or equal to (ISO 8601 format)", "schema": { - "type": "boolean" + "type": "string" } }, { - "name": "imitation", + "name": "to", "required": false, "in": "query", - "description": "Include imitation transactions in results (default: true, set to false to exclude)", + "description": "Filter by recipient address (0x prefixed hex string)", "schema": { - "type": "boolean" + "type": "string" } }, { - "name": "timezone", + "name": "value", "required": false, "in": "query", - "description": "IANA timezone identifier for date formatting (e.g., \"America/New_York\")", + "description": "Filter by transfer value in wei", + "schema": { + "type": "string" + } + }, + { + "name": "token_address", + "required": false, + "in": "query", + "description": "Filter by token contract address (0x prefixed hex string for ERC-20 tokens)", "schema": { "type": "string" } @@ -5430,26 +5827,26 @@ ], "responses": { "200": { - "description": "Paginated list of historical transactions", + "description": "Paginated list of incoming transfers", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/TransactionItemPage" + "$ref": "#/components/schemas/IncomingTransferPage" } } } } }, - "summary": "Get transaction history", + "summary": "Get incoming transfers", "tags": [ "transactions" ] } }, - "/v1/chains/{chainId}/transactions/{safeAddress}/propose": { + "/v1/chains/{chainId}/transactions/{safeAddress}/preview": { "post": { - "description": "Proposes a new multisig transaction for a Safe. The transaction will be pending until enough owners sign it to reach the required threshold.", - "operationId": "transactionsProposeTransactionV1", + "description": "Simulates a transaction execution to preview its effects, including gas estimates, balance changes, and potential errors before actually proposing or executing it.", + "operationId": "transactionsPreviewTransactionV1", "parameters": [ { "name": "chainId", @@ -5473,7 +5870,217 @@ ], "requestBody": { "required": true, - "description": "Transaction proposal including recipient, value, data, and initial signature", + "description": "Transaction data to preview including recipient, value, data, and operation type", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PreviewTransactionDto" + } + } + } + }, + "responses": { + "200": { + "description": "Transaction preview with simulation results, gas estimates, and potential effects", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransactionPreview" + } + } + } + }, + "400": { + "description": "Invalid transaction data or simulation failed" + }, + "404": { + "description": "Safe not found" + } + }, + "summary": "Preview transaction", + "tags": [ + "transactions" + ] + } + }, + "/v1/chains/{chainId}/safes/{safeAddress}/transactions/queued": { + "get": { + "description": "Retrieves a paginated list of queued (pending) transactions for a Safe that are waiting for execution, ordered by nonce.", + "operationId": "transactionsGetTransactionQueueV1", + "parameters": [ + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where the Safe is deployed", + "schema": { + "example": "1", + "type": "string" + } + }, + { + "name": "safeAddress", + "required": true, + "in": "path", + "description": "Safe contract address (0x prefixed hex string)", + "schema": { + "type": "string" + } + }, + { + "name": "trusted", + "required": false, + "in": "query", + "description": "Filter by trust status (true for trusted transactions, false for untrusted)", + "schema": { + "type": "boolean" + } + }, + { + "name": "cursor", + "required": false, + "in": "query", + "description": "Pagination cursor for retrieving the next set of results", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of queued transactions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueuedItemPage" + } + } + } + } + }, + "summary": "Get transaction queue", + "tags": [ + "transactions" + ] + } + }, + "/v1/chains/{chainId}/safes/{safeAddress}/transactions/history": { + "get": { + "description": "Retrieves a paginated list of executed transactions for a Safe, including multisig transactions, module transactions, and incoming transfers, ordered by execution date.", + "operationId": "transactionsGetTransactionsHistoryV1", + "parameters": [ + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where the Safe is deployed", + "schema": { + "example": "1", + "type": "string" + } + }, + { + "name": "safeAddress", + "required": true, + "in": "path", + "description": "Safe contract address (0x prefixed hex string)", + "schema": { + "type": "string" + } + }, + { + "name": "timezone_offset", + "required": false, + "in": "query", + "deprecated": true, + "description": "Deprecated: Timezone offset in milliseconds for date formatting (use timezone parameter instead)", + "schema": { + "type": "string" + } + }, + { + "name": "trusted", + "required": false, + "in": "query", + "description": "Filter by trust status (default: true, set to false to include untrusted transactions)", + "schema": { + "type": "boolean" + } + }, + { + "name": "imitation", + "required": false, + "in": "query", + "description": "Include imitation transactions in results (default: true, set to false to exclude)", + "schema": { + "type": "boolean" + } + }, + { + "name": "timezone", + "required": false, + "in": "query", + "description": "IANA timezone identifier for date formatting (e.g., \"America/New_York\")", + "schema": { + "type": "string" + } + }, + { + "name": "cursor", + "required": false, + "in": "query", + "description": "Pagination cursor for retrieving the next set of results", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of historical transactions", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TransactionItemPage" + } + } + } + } + }, + "summary": "Get transaction history", + "tags": [ + "transactions" + ] + } + }, + "/v1/chains/{chainId}/transactions/{safeAddress}/propose": { + "post": { + "description": "Proposes a new multisig transaction for a Safe. The transaction will be pending until enough owners sign it to reach the required threshold.", + "operationId": "transactionsProposeTransactionV1", + "parameters": [ + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where the Safe is deployed", + "schema": { + "example": "1", + "type": "string" + } + }, + { + "name": "safeAddress", + "required": true, + "in": "path", + "description": "Safe contract address (0x prefixed hex string)", + "schema": { + "type": "string" + } + } + ], + "requestBody": { + "required": true, + "description": "Transaction proposal including recipient, value, data, and initial signature", "content": { "application/json": { "schema": { @@ -5641,7 +6248,7 @@ "/v1/chains/{chainId}/delegates": { "get": { "deprecated": true, - "description": "Retrieves a paginated list of delegates for a specific chain. This endpoint is deprecated, please use the v2 version instead.", + "description": "Retrieves a paginated list of delegates for a specific chain. This endpoint is deprecated, please use the v3 version instead.", "operationId": "delegatesGetDelegatesV1", "parameters": [ { @@ -5719,7 +6326,7 @@ }, "post": { "deprecated": true, - "description": "Creates a new delegate for a specific chain. This endpoint is deprecated, please use the v2 version instead.", + "description": "Creates a new delegate for a specific chain. This endpoint is deprecated, please use the v3 version instead.", "operationId": "delegatesPostDelegateV1", "parameters": [ { @@ -5761,7 +6368,7 @@ "/v1/chains/{chainId}/delegates/{delegateAddress}": { "delete": { "deprecated": true, - "description": "Deletes a delegate for a specific chain and address. This endpoint is deprecated, please use the v2 version instead.", + "description": "Deletes a delegate for a specific chain and address. This endpoint is deprecated, please use the v3 version instead.", "operationId": "delegatesDeleteDelegateV1", "parameters": [ { @@ -5812,7 +6419,7 @@ "/v1/chains/{chainId}/safes/{safeAddress}/delegates/{delegateAddress}": { "delete": { "deprecated": true, - "description": "Removes a delegate from a specific Safe. This endpoint is deprecated, please use the v2 version instead.", + "description": "Removes a delegate from a specific Safe. This endpoint is deprecated, please use the v3 version instead.", "operationId": "delegatesDeleteSafeDelegateV1", "parameters": [ { @@ -5871,7 +6478,8 @@ }, "/v2/chains/{chainId}/delegates": { "get": { - "description": "Retrieves a paginated list of delegates for a specific chain with optional filtering by Safe, delegate, delegator, or label.", + "deprecated": true, + "description": "Retrieves a paginated list of delegates for a specific chain with optional filtering by Safe, delegate, delegator, or label. This endpoint is deprecated, please use the v3 version instead.", "operationId": "delegatesGetDelegatesV2", "parameters": [ { @@ -5942,13 +6550,14 @@ } } }, - "summary": "Get delegates", + "summary": "Get delegates (deprecated)", "tags": [ "delegates" ] }, "post": { - "description": "Creates a new delegate relationship between a Safe and a delegate address. Requires proper authorization signature.", + "deprecated": true, + "description": "Creates a new delegate relationship between a Safe and a delegate address. Requires proper authorization signature. This endpoint is deprecated, please use the v3 version instead.", "operationId": "delegatesPostDelegateV2", "parameters": [ { @@ -5981,7 +6590,7 @@ "description": "Invalid delegate data, signature, or unauthorized creation attempt" } }, - "summary": "Create delegate", + "summary": "Create delegate (deprecated)", "tags": [ "delegates" ] @@ -5989,7 +6598,8 @@ }, "/v2/chains/{chainId}/delegates/{delegateAddress}": { "delete": { - "description": "Removes a delegate relationship for a specific delegate address. Requires proper authorization signature.", + "deprecated": true, + "description": "Removes a delegate relationship for a specific delegate address. Requires proper authorization signature. This endpoint is deprecated, please use the v3 version instead.", "operationId": "delegatesDeleteDelegateV2", "parameters": [ { @@ -6031,202 +6641,239 @@ "description": "Invalid signature or unauthorized deletion attempt" } }, - "summary": "Delete delegate", + "summary": "Delete delegate (deprecated)", "tags": [ "delegates" ] } }, - "/v1/register/notifications": { - "post": { - "deprecated": true, - "description": "Registers a device to receive push notifications for Safe events. This endpoint is deprecated, please use the v2 version instead.", - "operationId": "notificationsRegisterDeviceV1", - "parameters": [], - "requestBody": { - "required": true, - "description": "Device registration data including device token, UUID, and Safe registrations with signatures", - "content": { - "application/json": { - "schema": { - "$ref": "#/components/schemas/RegisterDeviceDto" - } + "/v3/chains/{chainId}/delegates": { + "get": { + "description": "Retrieves a paginated list of delegates for a specific chain with optional filtering by Safe, delegate, delegator, or label.", + "operationId": "delegatesGetDelegatesV3", + "parameters": [ + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where delegates are registered", + "schema": { + "example": "1", + "type": "string" } - } - }, - "responses": { - "200": { - "description": "Device registered successfully for notifications" }, - "400": { - "description": "Invalid device data, expired timestamp, or invalid signature" - } - }, - "summary": "Register device for notifications (deprecated)", + { + "name": "cursor", + "required": false, + "in": "query", + "description": "Pagination cursor for retrieving the next set of results", + "schema": { + "type": "string" + } + }, + { + "name": "label", + "required": false, + "in": "query", + "description": "Filter by delegate label or name", + "schema": { + "type": "string" + } + }, + { + "name": "delegator", + "required": false, + "in": "query", + "description": "Filter by delegator address (0x prefixed hex string)", + "schema": { + "type": "string" + } + }, + { + "name": "delegate", + "required": false, + "in": "query", + "description": "Filter by delegate address (0x prefixed hex string)", + "schema": { + "type": "string" + } + }, + { + "name": "safe", + "required": false, + "in": "query", + "description": "Filter by Safe address (0x prefixed hex string)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "Paginated list of delegates retrieved successfully", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DelegatePage" + } + } + } + } + }, + "summary": "Get delegates", "tags": [ - "notifications" + "delegates" ] - } - }, - "/v1/chains/{chainId}/notifications/devices/{uuid}": { - "delete": { - "deprecated": true, - "description": "Removes a device from receiving notifications. This endpoint is deprecated, please use the v2 version instead.", - "operationId": "notificationsUnregisterDeviceV1", + }, + "post": { + "description": "Creates a new delegate relationship between a Safe and a delegate address. Requires proper authorization signature.", + "operationId": "delegatesPostDelegateV3", "parameters": [ { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID (kept for backward compatibility)", + "description": "Chain ID where the delegate will be registered", "schema": { "example": "1", "type": "string" } + } + ], + "requestBody": { + "required": true, + "description": "Delegate creation data including Safe address, delegate address, label, and authorization signature", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CreateDelegateDto" + } + } + } + }, + "responses": { + "204": { + "description": "Delegate created successfully" }, + "400": { + "description": "Invalid delegate data, signature, or unauthorized creation attempt" + } + }, + "summary": "Create delegate", + "tags": [ + "delegates" + ] + }, + "patch": { + "description": "Updates an existing delegate relationship (e.g. the delegate label). Requires proper authorization signature.", + "operationId": "delegatesUpdateDelegateV3", + "parameters": [ { - "name": "uuid", + "name": "chainId", "required": true, "in": "path", - "description": "Device UUID to unregister", + "description": "Chain ID where the delegate is registered", "schema": { - "example": "550e8400-e29b-41d4-a716-446655440000", + "example": "1", "type": "string" } } ], + "requestBody": { + "required": true, + "description": "Delegate update data including Safe address, delegate address, delegator, label, and authorization signature", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpdateDelegateV3Dto" + } + } + } + }, "responses": { "204": { - "description": "Device unregistered successfully" + "description": "Delegate updated successfully" + }, + "400": { + "description": "Invalid delegate data, signature, or unauthorized update attempt" } }, - "summary": "Unregister device (deprecated)", + "summary": "Update delegate", "tags": [ - "notifications" + "delegates" ] } }, - "/v1/chains/{chainId}/notifications/devices/{uuid}/safes/{safeAddress}": { + "/v3/chains/{chainId}/delegates/{delegateAddress}": { "delete": { - "deprecated": true, - "description": "Removes a specific Safe from receiving notifications on a device. This endpoint is deprecated, please use the v2 version instead.", - "operationId": "notificationsUnregisterSafeV1", + "description": "Removes a delegate relationship for a specific delegate address. Requires proper authorization signature.", + "operationId": "delegatesDeleteDelegateV3", "parameters": [ { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", + "description": "Chain ID where the delegate is registered", "schema": { "example": "1", "type": "string" } }, { - "name": "uuid", - "required": true, - "in": "path", - "description": "Device UUID", - "schema": { - "example": "550e8400-e29b-41d4-a716-446655440000", - "type": "string" - } - }, - { - "name": "safeAddress", + "name": "delegateAddress", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", + "description": "Delegate address to remove (0x prefixed hex string)", "schema": { "type": "string" } } ], - "responses": { - "204": { - "description": "Safe unregistered from device notifications successfully" - } - }, - "summary": "Unregister Safe from device (deprecated)", - "tags": [ - "notifications" - ] - } - }, - "/v2/register/notifications": { - "post": { - "description": "Registers or updates a device to receive push notifications for Safe events. Creates subscriptions for specified Safes and notification types.", - "operationId": "notificationsUpsertSubscriptionsV2", - "parameters": [], "requestBody": { "required": true, - "description": "Device and subscription data including device token, Safe addresses, and notification preferences", + "description": "Signature and data proving authorization to delete the delegate", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/UpsertSubscriptionsDto" + "$ref": "#/components/schemas/DeleteDelegateV3Dto" } } } }, "responses": { - "201": { - "description": "Device registered successfully with returned device UUID", - "content": { - "application/json": { - "schema": { - "type": "object", - "properties": { - "deviceUuid": { - "type": "string", - "format": "uuid", - "description": "Generated UUID for the registered device" - } - } - } - } - } + "204": { + "description": "Delegate deleted successfully" }, "400": { - "description": "Invalid device data or subscription configuration" + "description": "Invalid signature or unauthorized deletion attempt" } }, - "summary": "Register device for notifications", + "summary": "Delete delegate", "tags": [ - "notifications" + "delegates" ] } }, - "/v2/chains/{chainId}/notifications/devices/{deviceUuid}/safes/{safeAddress}": { + "/v1/chains/{chainId}/tokens/{address}": { "get": { - "description": "Retrieves the notification types that a device is subscribed to for a specific Safe.", - "operationId": "notificationsGetSafeSubscriptionV2", + "description": "Symbol, name, decimals, logo and trust flag of a token on the given chain, as known by the Transaction Service.", + "operationId": "tokensGetTokenV1", "parameters": [ - { - "name": "deviceUuid", - "required": true, - "in": "path", - "description": "Device UUID", - "schema": { - "example": "550e8400-e29b-41d4-a716-446655440000", - "type": "string" - } - }, { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", + "description": "Chain ID the token is deployed on", "schema": { "example": "1", "type": "string" } }, { - "name": "safeAddress", + "name": "address", "required": true, "in": "path", - "description": "Safe contract address (0x prefixed hex string)", + "description": "Token contract address (0x prefixed hex string)", "schema": { "type": "string" } @@ -6234,111 +6881,140 @@ ], "responses": { "200": { - "description": "List of notification types the device is subscribed to for this Safe", + "description": "Token metadata", "content": { "application/json": { "schema": { - "type": "array", - "items": { - "$ref": "#/components/schemas/NotificationTypeResponseDto" - } + "oneOf": [ + { + "$ref": "#/components/schemas/NativeTokenMetadata" + }, + { + "$ref": "#/components/schemas/Erc20TokenMetadata" + }, + { + "$ref": "#/components/schemas/Erc721TokenMetadata" + } + ] } } } }, - "401": { - "description": "Authentication required - valid JWT token must be provided" - }, "404": { - "description": "Device, Safe, or subscription not found" + "description": "The Transaction Service does not know this token" + }, + "422": { + "description": "Invalid chain ID or address" + }, + "429": { + "description": "Rate limit exceeded" } }, - "summary": "Get Safe subscription", + "summary": "Get token metadata", "tags": [ - "notifications" + "tokens" ] - }, - "delete": { - "description": "Removes all notification subscriptions for a specific Safe on a device.", - "operationId": "notificationsDeleteSubscriptionV2", + } + }, + "/v1/chains/{chainId}/tokens": { + "get": { + "description": "Metadata for up to 20 tokens of one chain, in request order. Addresses the Transaction Service does not know are omitted.", + "operationId": "tokensGetTokensV1", "parameters": [ - { - "name": "deviceUuid", - "required": true, - "in": "path", - "description": "Device UUID", - "schema": { - "example": "550e8400-e29b-41d4-a716-446655440000", - "type": "string" - } - }, { "name": "chainId", "required": true, "in": "path", - "description": "Chain ID where the Safe is deployed", + "description": "Chain ID the token is deployed on", "schema": { "example": "1", "type": "string" } }, { - "name": "safeAddress", + "name": "addresses", "required": true, - "in": "path", - "description": "Safe contract address (0x prefixed hex string)", + "in": "query", + "description": "Comma-separated token contract addresses, at most 20", "schema": { + "example": "0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48,0xdAC17F958D2ee523a2206206994597C13D831ec7", "type": "string" } } ], "responses": { - "204": { - "description": "Safe subscription deleted successfully" + "200": { + "description": "Token metadata for the known addresses, in request order", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/NativeTokenMetadata" + }, + { + "$ref": "#/components/schemas/Erc20TokenMetadata" + }, + { + "$ref": "#/components/schemas/Erc721TokenMetadata" + } + ] + } + } + } + } }, - "404": { - "description": "Device, Safe, or subscription not found" + "422": { + "description": "Invalid chain ID, malformed address, empty list or more than 20 addresses" + }, + "429": { + "description": "Rate limit exceeded" } }, - "summary": "Delete Safe subscription", + "summary": "Get metadata for several tokens", "tags": [ - "notifications" + "tokens" ] } }, - "/v2/notifications/subscriptions": { - "delete": { - "description": "Delete all subscriptions of a Safe on a device. This will delete all subscriptions of a Safe on a device for all chains passed in the request body.", - "operationId": "notificationsDeleteAllSubscriptionsV2", + "/v1/register/notifications": { + "post": { + "deprecated": true, + "description": "Registers a device to receive push notifications for Safe events. This endpoint is deprecated, please use the v2 version instead.", + "operationId": "notificationsRegisterDeviceV1", "parameters": [], "requestBody": { "required": true, + "description": "Device registration data including device token, UUID, and Safe registrations with signatures", "content": { "application/json": { "schema": { - "$ref": "#/components/schemas/DeleteAllSubscriptionsDto" + "$ref": "#/components/schemas/RegisterDeviceDto" } } } }, "responses": { - "404": { - "description": "No subscription was found" + "200": { + "description": "Device registered successfully for notifications" }, - "422": { - "description": "The request body is invalid" + "400": { + "description": "Invalid device data, expired timestamp, or invalid signature" } }, - "summary": "Delete all subscriptions of a device", + "summary": "Register device for notifications (deprecated)", "tags": [ "notifications" ] } }, - "/v2/chains/{chainId}/notifications/devices/{deviceUuid}": { + "/v1/chains/{chainId}/notifications/devices/{uuid}": { "delete": { - "description": "Removes a device and all its notification subscriptions from the system.", - "operationId": "notificationsDeleteDeviceV2", + "deprecated": true, + "description": "Removes a device from receiving notifications. This endpoint is deprecated, please use the v2 version instead.", + "operationId": "notificationsUnregisterDeviceV1", "parameters": [ { "name": "chainId", @@ -6351,10 +7027,10 @@ } }, { - "name": "deviceUuid", + "name": "uuid", "required": true, "in": "path", - "description": "Device UUID to delete", + "description": "Device UUID to unregister", "schema": { "example": "550e8400-e29b-41d4-a716-446655440000", "type": "string" @@ -6363,131 +7039,397 @@ ], "responses": { "204": { - "description": "Device deleted successfully" - }, - "404": { - "description": "Device not found" + "description": "Device unregistered successfully" } }, - "summary": "Delete device", + "summary": "Unregister device (deprecated)", "tags": [ "notifications" ] } - } - }, - "info": { - "title": "Safe Client Gateway", - "description": "", - "version": "main", - "contact": {} - }, - "tags": [], - "servers": [], - "components": { - "schemas": { - "About": { - "type": "object", - "properties": { - "name": { - "type": "string" + }, + "/v1/chains/{chainId}/notifications/devices/{uuid}/safes/{safeAddress}": { + "delete": { + "deprecated": true, + "description": "Removes a specific Safe from receiving notifications on a device. This endpoint is deprecated, please use the v2 version instead.", + "operationId": "notificationsUnregisterSafeV1", + "parameters": [ + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where the Safe is deployed", + "schema": { + "example": "1", + "type": "string" + } }, - "version": { - "type": "string", - "nullable": true + { + "name": "uuid", + "required": true, + "in": "path", + "description": "Device UUID", + "schema": { + "example": "550e8400-e29b-41d4-a716-446655440000", + "type": "string" + } }, - "buildNumber": { - "type": "string", - "nullable": true + { + "name": "safeAddress", + "required": true, + "in": "path", + "description": "Safe contract address (0x prefixed hex string)", + "schema": { + "type": "string" + } } - }, - "required": [ - "name" - ] - }, - "UserSession": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "authMethod": { - "type": "string", - "enum": [ - "siwe", - "oidc" - ] - }, - "signerAddress": { - "type": "string", - "description": "Wallet signer address. Present only for SIWE-authenticated users." - }, - "email": { - "type": "string", - "description": "Verified email address. Present only for OIDC-authenticated users when stored." + ], + "responses": { + "204": { + "description": "Safe unregistered from device notifications successfully" } }, - "required": [ - "id", - "authMethod" + "summary": "Unregister Safe from device (deprecated)", + "tags": [ + "notifications" ] - }, - "AuthNonce": { - "type": "object", - "properties": { - "nonce": { - "type": "string" + } + }, + "/v2/register/notifications": { + "post": { + "description": "Registers or updates a device to receive push notifications for Safe events. Creates subscriptions for specified Safes and notification types.", + "operationId": "notificationsUpsertSubscriptionsV2", + "parameters": [], + "requestBody": { + "required": true, + "description": "Device and subscription data including device token, Safe addresses, and notification preferences", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UpsertSubscriptionsDto" + } + } } }, - "required": [ - "nonce" - ] - }, - "SiweDto": { - "type": "object", - "properties": { - "message": { - "type": "string" + "responses": { + "201": { + "description": "Device registered successfully with returned device UUID", + "content": { + "application/json": { + "schema": { + "type": "object", + "properties": { + "deviceUuid": { + "type": "string", + "format": "uuid", + "description": "Generated UUID for the registered device" + } + } + } + } + } }, - "signature": { - "type": "string" + "400": { + "description": "Invalid device data or subscription configuration" } }, - "required": [ - "message", - "signature" + "summary": "Register device for notifications", + "tags": [ + "notifications" ] - }, - "LogoutDto": { - "type": "object", - "properties": { - "redirect_url": { - "type": "string", - "description": "Post-logout redirect URL (must be same-origin as pre-configured URL)" - } - } - }, - "Authenticator": { - "type": "object", - "properties": { - "id": { - "type": "string", - "description": "Auth0 authentication method identifier (e.g. totp|...)" - }, - "type": { - "type": "string", - "description": "Authentication method type (e.g. totp)" + } + }, + "/v2/chains/{chainId}/notifications/devices/{deviceUuid}/safes/{safeAddress}": { + "get": { + "description": "Retrieves the notification types that a device is subscribed to for a specific Safe.", + "operationId": "notificationsGetSafeSubscriptionV2", + "parameters": [ + { + "name": "deviceUuid", + "required": true, + "in": "path", + "description": "Device UUID", + "schema": { + "example": "550e8400-e29b-41d4-a716-446655440000", + "type": "string" + } }, - "name": { - "type": "string", - "description": "User-visible authenticator name" + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where the Safe is deployed", + "schema": { + "example": "1", + "type": "string" + } }, - "createdAt": { - "type": "string", - "description": "ISO 8601 timestamp of when the method was enrolled" + { + "name": "safeAddress", + "required": true, + "in": "path", + "description": "Safe contract address (0x prefixed hex string)", + "schema": { + "type": "string" + } } - }, - "required": [ + ], + "responses": { + "200": { + "description": "List of notification types the device is subscribed to for this Safe", + "content": { + "application/json": { + "schema": { + "type": "array", + "items": { + "$ref": "#/components/schemas/NotificationTypeResponseDto" + } + } + } + } + }, + "401": { + "description": "Authentication required - valid JWT token must be provided" + }, + "404": { + "description": "Device, Safe, or subscription not found" + } + }, + "summary": "Get Safe subscription", + "tags": [ + "notifications" + ] + }, + "delete": { + "description": "Removes all notification subscriptions for a specific Safe on a device.", + "operationId": "notificationsDeleteSubscriptionV2", + "parameters": [ + { + "name": "deviceUuid", + "required": true, + "in": "path", + "description": "Device UUID", + "schema": { + "example": "550e8400-e29b-41d4-a716-446655440000", + "type": "string" + } + }, + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID where the Safe is deployed", + "schema": { + "example": "1", + "type": "string" + } + }, + { + "name": "safeAddress", + "required": true, + "in": "path", + "description": "Safe contract address (0x prefixed hex string)", + "schema": { + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Safe subscription deleted successfully" + }, + "404": { + "description": "Device, Safe, or subscription not found" + } + }, + "summary": "Delete Safe subscription", + "tags": [ + "notifications" + ] + } + }, + "/v2/notifications/subscriptions": { + "delete": { + "description": "Delete all subscriptions of a Safe on a device. This will delete all subscriptions of a Safe on a device for all chains passed in the request body.", + "operationId": "notificationsDeleteAllSubscriptionsV2", + "parameters": [], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DeleteAllSubscriptionsDto" + } + } + } + }, + "responses": { + "404": { + "description": "No subscription was found" + }, + "422": { + "description": "The request body is invalid" + } + }, + "summary": "Delete all subscriptions of a device", + "tags": [ + "notifications" + ] + } + }, + "/v2/chains/{chainId}/notifications/devices/{deviceUuid}": { + "delete": { + "description": "Removes a device and all its notification subscriptions from the system.", + "operationId": "notificationsDeleteDeviceV2", + "parameters": [ + { + "name": "chainId", + "required": true, + "in": "path", + "description": "Chain ID (kept for backward compatibility)", + "schema": { + "example": "1", + "type": "string" + } + }, + { + "name": "deviceUuid", + "required": true, + "in": "path", + "description": "Device UUID to delete", + "schema": { + "example": "550e8400-e29b-41d4-a716-446655440000", + "type": "string" + } + } + ], + "responses": { + "204": { + "description": "Device deleted successfully" + }, + "404": { + "description": "Device not found" + } + }, + "summary": "Delete device", + "tags": [ + "notifications" + ] + } + } + }, + "info": { + "title": "Safe Client Gateway", + "description": "", + "version": "main-2a92a92", + "contact": {} + }, + "tags": [], + "servers": [], + "components": { + "schemas": { + "About": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "version": { + "type": "string", + "nullable": true + }, + "buildNumber": { + "type": "string", + "nullable": true + } + }, + "required": [ + "name" + ] + }, + "UserSession": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "authMethod": { + "type": "string", + "enum": [ + "siwe", + "oidc" + ] + }, + "signerAddress": { + "type": "string", + "description": "Wallet signer address. Present only for SIWE-authenticated users." + }, + "email": { + "type": "string", + "description": "Verified email address. Present only for OIDC-authenticated users when stored." + } + }, + "required": [ + "id", + "authMethod" + ] + }, + "AuthNonce": { + "type": "object", + "properties": { + "nonce": { + "type": "string" + } + }, + "required": [ + "nonce" + ] + }, + "SiweDto": { + "type": "object", + "properties": { + "message": { + "type": "string" + }, + "signature": { + "type": "string" + } + }, + "required": [ + "message", + "signature" + ] + }, + "LogoutDto": { + "type": "object", + "properties": { + "redirect_url": { + "type": "string", + "description": "Post-logout redirect URL (must be same-origin as pre-configured URL)" + } + } + }, + "Authenticator": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Auth0 authentication method identifier (e.g. totp|...)" + }, + "type": { + "type": "string", + "description": "Authentication method type (e.g. totp)" + }, + "name": { + "type": "string", + "description": "User-visible authenticator name" + }, + "createdAt": { + "type": "string", + "description": "ISO 8601 timestamp of when the method was enrolled" + } + }, + "required": [ "id", "type" ] @@ -6778,6 +7720,10 @@ "metadata": { "type": "object", "nullable": true + }, + "hasPaymentMethod": { + "type": "boolean", + "description": "Whether the subscription has a default payment method, or its customer does as a fallback" } }, "required": [ @@ -6925,9 +7871,6 @@ "id": { "type": "string" }, - "url": { - "type": "string" - }, "active": { "type": "boolean" }, @@ -6945,11 +7888,14 @@ "items": { "type": "object" } + }, + "trialPeriodDays": { + "type": "number", + "nullable": true } }, "required": [ "id", - "url", "active", "metadata" ] @@ -6969,6 +7915,106 @@ "url" ] }, + "PreviewLineItem": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "amount": { + "type": "number", + "description": "Signed amount in minor units; negative for credit on unused time" + }, + "currency": { + "type": "string" + } + }, + "required": [ + "description", + "amount", + "currency" + ] + }, + "SubscriptionUpdatePreview": { + "type": "object", + "properties": { + "amountDue": { + "type": "number" + }, + "currency": { + "type": "string" + }, + "nextBillingDate": { + "type": "number", + "description": "Unix timestamp in seconds" + }, + "lineItems": { + "type": "array", + "items": { + "$ref": "#/components/schemas/PreviewLineItem" + } + } + }, + "required": [ + "amountDue", + "currency", + "nextBillingDate", + "lineItems" + ] + }, + "RemovedSafeDto": { + "type": "object", + "properties": { + "chainId": { + "type": "string" + }, + "address": { + "type": "string" + } + }, + "required": [ + "chainId", + "address" + ] + }, + "UpdateSubscriptionDto": { + "type": "object", + "properties": { + "planId": { + "type": "string", + "description": "The price id of the plan to move the subscription onto" + }, + "paymentLinkId": { + "type": "string", + "description": "Which offered payment link sells that plan. Only needed to disambiguate when several do" + }, + "removedSafes": { + "description": "Safes to remove from the workspace before the plan changes, so it fits the new plan. Safes the workspace does not hold are ignored", + "type": "array", + "items": { + "$ref": "#/components/schemas/RemovedSafeDto" + } + } + }, + "required": [ + "planId" + ] + }, + "UpdateSubscriptionResult": { + "type": "object", + "properties": { + "subscriptionId": { + "type": "string" + }, + "success": { + "type": "boolean" + } + }, + "required": [ + "subscriptionId", + "success" + ] + }, "CheckoutSession": { "type": "object", "properties": { @@ -7713,17 +8759,33 @@ "type": "boolean" }, "safeTransactionSponsored": { - "type": "boolean" + "type": "boolean", + "deprecated": true, + "description": "Use gasPaymentOptions instead." }, "enableTenderlySimulationBeforeRelay": { "type": "boolean" + }, + "gasPaymentOptions": { + "type": "array", + "description": "Who may pay for a relayed transaction on this chain.", + "items": { + "type": "string", + "enum": [ + "FREE_DAILY_LIMIT", + "SUBSCRIPTION", + "PAY_FROM_SAFE", + "NO_FEE_CAMPAIGN" + ] + } } }, "required": [ "type", "safeCreationSponsored", "safeTransactionSponsored", - "enableTenderlySimulationBeforeRelay" + "enableTenderlySimulationBeforeRelay", + "gasPaymentOptions" ] }, "Chain": { @@ -9182,6 +10244,29 @@ "signature" ] }, + "SafeAppInfo": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "name": { + "type": "string" + }, + "url": { + "type": "string" + }, + "logoUri": { + "type": "string", + "nullable": true + } + }, + "required": [ + "id", + "name", + "url" + ] + }, "Message": { "type": "object", "properties": { @@ -9197,11 +10282,13 @@ }, "logoUri": { "type": "string", - "nullable": true + "nullable": true, + "deprecated": true }, "name": { "type": "string", - "nullable": true + "nullable": true, + "deprecated": true }, "message": { "oneOf": [ @@ -9226,7 +10313,13 @@ "type": "number" }, "proposedBy": { - "$ref": "#/components/schemas/AddressInfo" + "nullable": true, + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AddressInfo" + } + ] }, "confirmations": { "type": "array", @@ -9241,18 +10334,38 @@ "origin": { "type": "string", "nullable": true + }, + "safeAppInfo": { + "nullable": true, + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/SafeAppInfo" + } + ] + }, + "safeAppId": { + "type": "number", + "nullable": true, + "deprecated": true } }, "required": [ "messageHash", "status", + "logoUri", + "name", "message", "creationTimestamp", "modifiedTimestamp", "confirmationsSubmitted", "confirmationsRequired", "proposedBy", - "confirmations" + "confirmations", + "preparedSignature", + "origin", + "safeAppInfo", + "safeAppId" ] }, "MessageItem": { @@ -9270,11 +10383,13 @@ }, "logoUri": { "type": "string", - "nullable": true + "nullable": true, + "deprecated": true }, "name": { "type": "string", - "nullable": true + "nullable": true, + "deprecated": true }, "message": { "oneOf": [ @@ -9299,7 +10414,13 @@ "type": "number" }, "proposedBy": { - "$ref": "#/components/schemas/AddressInfo" + "nullable": true, + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AddressInfo" + } + ] }, "confirmations": { "type": "array", @@ -9315,6 +10436,20 @@ "type": "string", "nullable": true }, + "safeAppInfo": { + "nullable": true, + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/SafeAppInfo" + } + ] + }, + "safeAppId": { + "type": "number", + "nullable": true, + "deprecated": true + }, "type": { "type": "string", "enum": [ @@ -9325,6 +10460,8 @@ "required": [ "messageHash", "status", + "logoUri", + "name", "message", "creationTimestamp", "modifiedTimestamp", @@ -9332,6 +10469,10 @@ "confirmationsRequired", "proposedBy", "confirmations", + "preparedSignature", + "origin", + "safeAppInfo", + "safeAppId", "type" ] }, @@ -9880,7 +11021,9 @@ "SAFE_ADDED", "SAFE_REMOVED", "ADDRESS_BOOK_UPSERTED", - "ADDRESS_BOOK_DELETED" + "ADDRESS_BOOK_DELETED", + "ADDRESS_BOOK_REQUEST_CREATED", + "ADDRESS_BOOK_REQUEST_REJECTED" ] }, "actorUserId": { @@ -9979,12 +11122,46 @@ "items": { "$ref": "#/components/schemas/SpaceSafeDto" } + }, + "addressBookItems": { + "description": "Address book entries to upsert for the added Safes, in the same transaction: if either write fails, neither is kept.", + "type": "array", + "items": { + "$ref": "#/components/schemas/AddressBookItem" + } } }, "required": [ "safes" ] }, + "GetSpacesSafesResponse": { + "type": "object", + "properties": { + "safes": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "example": { + "{chainId}": [ + "0x..." + ] + } + }, + "spaceUuid": { + "type": "string", + "description": "Space UUID" + } + }, + "required": [ + "safes", + "spaceUuid" + ] + }, "GetSpaceSafeResponse": { "type": "object", "properties": { @@ -10176,12 +11353,17 @@ "email": { "type": "string", "nullable": true + }, + "address": { + "type": "string", + "nullable": true } }, "required": [ "id", "status", - "email" + "email", + "address" ] }, "MemberDto": { @@ -10499,1384 +11681,2211 @@ "safes" ] }, - "SurveyOptionDto": { + "SingleRecipientAnalysisResultDto": { "type": "object", "properties": { - "key": { - "type": "string" + "severity": { + "type": "string", + "description": "Severity level indicating the importance and risk", + "enum": [ + "OK", + "INFO", + "WARN", + "CRITICAL" + ] }, - "label": { - "type": "string" + "type": { + "type": "string", + "description": "Recipient interaction status code", + "enum": [ + "NEW_RECIPIENT", + "RECURRING_RECIPIENT", + "LOW_ACTIVITY", + "FAILED" + ], + "example": "NEW_RECIPIENT" + }, + "title": { + "type": "string", + "description": "User-facing title of the finding" }, "description": { - "type": "string" + "type": "string", + "description": "Detailed description explaining the finding and its implications" }, - "icon": { - "type": "string" + "error": { + "type": "string", + "description": "Error message for failed analysis" } }, "required": [ - "key", - "label" - ] - }, - "SurveyPageDto": { - "type": "object", - "properties": { - "id": { - "type": "string" - }, - "title": { - "type": "string" - }, - "subtitle": { - "type": "string", - "nullable": true - }, - "multiSelect": { - "type": "boolean" - }, - "options": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SurveyOptionDto" - } - } - }, - "required": [ - "id", + "severity", + "type", "title", - "subtitle", - "multiSelect", - "options" + "description" ] }, - "SurveyContentDto": { + "SingleRecipientAnalysisDto": { "type": "object", "properties": { - "pages": { + "RECIPIENT_INTERACTION": { + "description": "Analysis results related to recipient interaction history. Shows whether this is a new or recurring recipient.", + "example": [ + { + "severity": "INFO", + "type": "NEW_RECIPIENT", + "title": "New recipient", + "description": "This is the first time you are interacting with this recipient." + } + ], "type": "array", "items": { - "$ref": "#/components/schemas/SurveyPageDto" + "$ref": "#/components/schemas/SingleRecipientAnalysisResultDto" + } + }, + "RECIPIENT_ACTIVITY": { + "description": "Analysis results related to recipient activity. Shows whether this is a low activity recipient. (Available only for Safes)", + "example": [ + { + "severity": "WARN", + "type": "LOW_ACTIVITY", + "title": "Low activity recipient", + "description": "This address has few transactions." + } + ], + "type": "array", + "items": { + "$ref": "#/components/schemas/SingleRecipientAnalysisResultDto" } + }, + "isSafe": { + "type": "boolean", + "description": "Indicates whether the analyzed recipient address is a Safe.", + "example": false } }, "required": [ - "pages" + "RECIPIENT_INTERACTION", + "isSafe" ] }, - "SurveyDto": { + "CounterpartyAnalysisRequestDto": { "type": "object", "properties": { - "id": { - "type": "number" - }, - "slug": { - "type": "string" - }, - "version": { - "type": "number" + "to": { + "type": "string", + "description": "Recipient address of the transaction." }, - "title": { - "type": "string" + "value": { + "type": "string", + "description": "Amount to send with the transaction." }, - "subtitle": { + "data": { "type": "string", - "nullable": true + "description": "Hex-encoded data payload for the transaction." }, - "surveyContent": { - "$ref": "#/components/schemas/SurveyContentDto" + "operation": { + "type": "number", + "enum": [ + 0, + 1 + ], + "description": "Operation type: 0 for CALL, 1 for DELEGATECALL." } }, "required": [ - "id", - "slug", - "version", - "title", - "subtitle", - "surveyContent" + "to", + "value", + "data", + "operation" ] }, - "SpaceSurveyResponseDto": { + "RecipientResultDto": { "type": "object", "properties": { - "surveyVersion": { - "type": "number" + "severity": { + "type": "string", + "description": "Severity level indicating the importance and risk", + "enum": [ + "OK", + "INFO", + "WARN", + "CRITICAL" + ] }, - "selections": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - }, - "description": "Map from page id → selected option keys" + "type": { + "type": "string", + "description": "Bridge compatibility status code", + "enum": [ + "NEW_RECIPIENT", + "RECURRING_RECIPIENT", + "LOW_ACTIVITY", + "INCOMPATIBLE_SAFE", + "MISSING_OWNERSHIP", + "UNSUPPORTED_NETWORK", + "DIFFERENT_SAFE_SETUP", + "FAILED" + ], + "example": "MISSING_OWNERSHIP" }, - "submittedAt": { - "format": "date-time", - "type": "string" + "title": { + "type": "string", + "description": "User-facing title of the finding" }, - "updatedAt": { - "format": "date-time", - "type": "string" + "description": { + "type": "string", + "description": "Detailed description explaining the finding and its implications" }, - "answeredByUserId": { - "type": "number", - "nullable": true + "error": { + "type": "string", + "description": "Error message for failed analysis" + }, + "targetChainId": { + "type": "string", + "description": "Target chain ID for bridge operations. Only present for BridgeStatus." } }, "required": [ - "surveyVersion", - "selections", - "submittedAt", - "updatedAt", - "answeredByUserId" + "severity", + "type", + "title", + "description" ] }, - "SurveyStateDto": { + "RecipientAnalysisDto": { "type": "object", "properties": { - "survey": { - "$ref": "#/components/schemas/SurveyDto" + "isSafe": { + "type": "boolean", + "description": "Indicates whether the analyzed recipient address is a Safe.", + "example": true }, - "surveyResponse": { - "nullable": true, - "type": "object", - "allOf": [ + "RECIPIENT_INTERACTION": { + "description": "Analysis results related to recipient interaction history. Shows whether this is a new or recurring recipient.", + "example": [ { - "$ref": "#/components/schemas/SpaceSurveyResponseDto" + "severity": "INFO", + "type": "NEW_RECIPIENT", + "title": "New recipient", + "description": "This is the first time you are interacting with this recipient." } - ] - } - }, - "required": [ - "survey", - "surveyResponse" - ] - }, - "SubmitSurveyResponseDto": { - "type": "object", - "properties": { - "selections": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" + ], + "type": "array", + "items": { + "$ref": "#/components/schemas/RecipientResultDto" + } + }, + "RECIPIENT_ACTIVITY": { + "description": "Analysis results related to recipient activity frequency. Shows whether this is a low activity recipient.", + "example": [ + { + "severity": "WARN", + "type": "LOW_ACTIVITY", + "title": "Low activity recipient", + "description": "This address has few transactions." } - }, - "description": "Map from page id → selected option keys", - "example": { - "use_cases": [ - "run_payments", - "hold_assets" - ] + ], + "type": "array", + "items": { + "$ref": "#/components/schemas/RecipientResultDto" + } + }, + "BRIDGE": { + "description": "Analysis results for cross-chain bridge operations. Identifies compatibility issues, ownership problems, or unsupported networks.", + "example": [ + { + "severity": "WARN", + "type": "MISSING_OWNERSHIP", + "title": "No ownership on target chain", + "description": "You do not have ownership of a Safe on the target chain.", + "targetChainId": "137" + } + ], + "type": "array", + "items": { + "$ref": "#/components/schemas/RecipientResultDto" } } }, "required": [ - "selections" + "isSafe" ] }, - "SurveyResponseResultDto": { + "ContractAnalysisResultDto": { "type": "object", "properties": { - "id": { - "type": "number" - }, - "spaceUuid": { + "severity": { "type": "string", - "description": "Space UUID" - }, - "surveySlug": { - "type": "string" - }, - "surveyVersion": { - "type": "number" - }, - "selections": { - "type": "object", - "additionalProperties": { - "type": "array", - "items": { - "type": "string" - } - } - }, - "submittedAt": { - "format": "date-time", - "type": "string" - }, - "updatedAt": { - "format": "date-time", - "type": "string" - }, - "answeredByUserId": { - "type": "number", - "nullable": true - } - }, - "required": [ - "id", - "spaceUuid", - "surveySlug", - "surveyVersion", - "selections", - "submittedAt", - "updatedAt", - "answeredByUserId" - ] - }, - "FeatureKey": { - "type": "string", - "enum": [ - "safe_seats" - ], - "description": "Feature key from the entitlements catalog." - }, - "BinaryEntitlement": { - "type": "object", - "properties": { - "feature": { - "description": "Feature key from the entitlements catalog.", - "allOf": [ - { - "$ref": "#/components/schemas/FeatureKey" - } + "description": "Severity level indicating the importance and risk", + "enum": [ + "OK", + "INFO", + "WARN", + "CRITICAL" ] }, - "enabled": { - "type": "boolean", - "description": "Whether the plan grants the feature at all. A metered feature reports its quota and usage even when this is false." - }, "type": { "type": "string", + "description": "Contract verification status code", "enum": [ - "binary" - ] + "VERIFIED", + "NOT_VERIFIED", + "NOT_VERIFIED_BY_SAFE", + "VERIFICATION_UNAVAILABLE", + "NEW_CONTRACT", + "KNOWN_CONTRACT", + "UNEXPECTED_DELEGATECALL", + "UNOFFICIAL_FALLBACK_HANDLER", + "FAILED" + ], + "example": "VERIFIED" + }, + "title": { + "type": "string", + "description": "User-facing title of the finding" + }, + "description": { + "type": "string", + "description": "Detailed description explaining the finding and its implications" + }, + "error": { + "type": "string", + "description": "Error message for failed analysis" } }, "required": [ - "feature", - "enabled", - "type" + "severity", + "type", + "title", + "description" ] }, - "ValueEntitlement": { + "FallbackHandlerInfoDto": { "type": "object", "properties": { - "feature": { - "description": "Feature key from the entitlements catalog.", - "allOf": [ - { - "$ref": "#/components/schemas/FeatureKey" - } - ] - }, - "enabled": { - "type": "boolean", - "description": "Whether the plan grants the feature at all. A metered feature reports its quota and usage even when this is false." + "address": { + "type": "string", + "description": "Address of the fallback handler contract" }, - "type": { + "name": { "type": "string", - "enum": [ - "value" - ] + "description": "Name of the fallback handler contract" }, - "value": { + "logoUrl": { "type": "string", - "nullable": true + "description": "Logo URL for the fallback handler contract" } }, "required": [ - "feature", - "enabled", - "type", - "value" + "address" ] }, - "MeteredEntitlement": { + "FallbackHandlerAnalysisResultDto": { "type": "object", "properties": { - "feature": { - "description": "Feature key from the entitlements catalog.", - "allOf": [ - { - "$ref": "#/components/schemas/FeatureKey" - } + "severity": { + "type": "string", + "description": "Severity level indicating the importance and risk", + "enum": [ + "OK", + "INFO", + "WARN", + "CRITICAL" ] }, - "enabled": { - "type": "boolean", - "description": "Whether the plan grants the feature at all. A metered feature reports its quota and usage even when this is false." - }, "type": { "type": "string", + "description": "Status code for unofficial fallback handler", "enum": [ - "metered" - ] + "UNOFFICIAL_FALLBACK_HANDLER" + ], + "example": "VERIFIED" }, - "quota": { - "type": "number", - "nullable": true, - "description": "The plan's quota, never inflated to match usage; null means unlimited." + "title": { + "type": "string", + "description": "User-facing title of the finding" }, - "used": { - "type": "number", - "description": "May legally exceed `quota`." + "description": { + "type": "string", + "description": "Detailed description explaining the finding and its implications" }, - "resetsAt": { - "format": "date-time", + "error": { "type": "string", - "nullable": true, - "description": "Null for stock-type features (seats) that have no reset window." + "description": "Error message for failed analysis" + }, + "fallbackHandler": { + "description": "Information about the fallback handler", + "allOf": [ + { + "$ref": "#/components/schemas/FallbackHandlerInfoDto" + } + ] } }, "required": [ - "feature", - "enabled", + "severity", "type", - "quota", - "used", - "resetsAt" + "title", + "description" ] }, - "EntitlementsPlan": { + "ContractAnalysisDto": { "type": "object", "properties": { - "id": { + "logoUrl": { "type": "string", - "description": "Plan identifier in the billing service" + "description": "Logo URL for the contract", + "example": "https://example.com/logo.png" }, "name": { "type": "string", - "nullable": true + "description": "Name of the contract", + "example": "Uniswap V3 Router" }, - "cycleEndsAt": { - "format": "date-time", - "type": "string", - "nullable": true, - "description": "End of the current billing cycle" - } - }, - "required": [ - "id", - "name", - "cycleEndsAt" - ] - }, - "EntitlementsResponse": { - "type": "object", - "properties": { - "plan": { - "nullable": true, - "description": "Null when the workspace has no active subscription.", - "type": "object", - "allOf": [ + "CONTRACT_VERIFICATION": { + "description": "Analysis results for contract verification status. Shows whether contracts are verified and source code is available.", + "example": [ { - "$ref": "#/components/schemas/EntitlementsPlan" + "severity": "INFO", + "type": "VERIFIED", + "title": "Verified contract", + "description": "This contract has been verified and its source code is available" } - ] + ], + "type": "array", + "items": { + "$ref": "#/components/schemas/ContractAnalysisResultDto" + } }, - "entitlements": { + "CONTRACT_INTERACTION": { + "description": "Analysis results related to contract interaction history. Shows whether this is a new or previously interacted contract.", + "example": [ + { + "severity": "INFO", + "type": "NEW_CONTRACT", + "title": "New contract", + "description": "This is the first time you are interacting with this contract" + } + ], "type": "array", - "description": "One entry per catalog feature. Which fields an entry carries is decided by `type`: a metered one always carries quota, usage and its reset window, and the others never do.", "items": { - "oneOf": [ - { - "$ref": "#/components/schemas/BinaryEntitlement" - }, - { - "$ref": "#/components/schemas/ValueEntitlement" - }, - { - "$ref": "#/components/schemas/MeteredEntitlement" - } - ], - "discriminator": { - "propertyName": "type", - "mapping": { - "binary": "#/components/schemas/BinaryEntitlement", - "value": "#/components/schemas/ValueEntitlement", - "metered": "#/components/schemas/MeteredEntitlement" - } + "$ref": "#/components/schemas/ContractAnalysisResultDto" + } + }, + "DELEGATECALL": { + "description": "Analysis results for delegatecall operations. Identifies unexpected or potentially dangerous delegate calls.", + "example": [ + { + "severity": "CRITICAL", + "type": "UNEXPECTED_DELEGATECALL", + "title": "Unexpected delegatecall", + "description": "An unexpected delegatecall operation was detected that could be dangerous" } + ], + "type": "array", + "items": { + "$ref": "#/components/schemas/ContractAnalysisResultDto" } - } - }, - "required": [ - "plan", - "entitlements" - ] - }, - "SafeList": { - "type": "object", - "properties": { - "safes": { + }, + "FALLBACK_HANDLER": { + "description": "Analysis results for setFallbackHandler operations. Identifies untrusted or unofficial fallback handlers in the transactions.", + "example": [ + { + "severity": "WARN", + "type": "UNOFFICIAL_FALLBACK_HANDLER", + "title": "Unofficial fallback handler", + "description": "Verify the fallback handler is trusted and secure before proceeding.", + "fallbackHandler": { + "address": "0x123", + "name": "CompatibilityFallbackHandler", + "logoUrl": "https://example.com/logo.png" + } + } + ], "type": "array", "items": { - "type": "string" + "$ref": "#/components/schemas/FallbackHandlerAnalysisResultDto" } } - }, - "required": [ - "safes" - ] + } }, - "RelayDto": { + "DeadlockAnalysisResultDto": { "type": "object", "properties": { - "version": { - "type": "string" - }, - "to": { - "type": "string" + "severity": { + "type": "string", + "description": "Severity level indicating the importance and risk", + "enum": [ + "OK", + "INFO", + "WARN", + "CRITICAL" + ] }, - "data": { - "type": "string" + "type": { + "type": "string", + "description": "Deadlock analysis status code", + "enum": [ + "DEADLOCK_DETECTED", + "NESTED_SAFE_WARNING", + "FAILED" + ], + "example": "DEADLOCK_DETECTED" }, - "gasLimit": { + "title": { "type": "string", - "nullable": true, - "description": "Accepted for backward compatibility and validation; not forwarded to the relay provider." + "description": "User-facing title of the finding" }, - "safeTxHash": { + "description": { "type": "string", - "description": "Safe transaction hash for relay-fee eligibility check" + "description": "Detailed description explaining the finding and its implications" }, - "acceptUnverifiedSimulation": { - "type": "boolean", - "description": "Set to true to proceed with the relay when a previous attempt returned INDETERMINATE_SIMULATION. The user has acknowledged the simulation could not be completed and accepts the risk." + "error": { + "type": "string", + "description": "Error message for failed analysis" } }, "required": [ - "version", - "to", - "data" + "severity", + "type", + "title", + "description" ] }, - "Relay": { + "DeadlockAnalysisDto": { "type": "object", "properties": { - "taskId": { - "type": "string" + "DEADLOCK": { + "description": "Deadlock analysis findings. Identifies signing deadlock risks in nested Safe configurations.", + "example": [ + { + "severity": "CRITICAL", + "type": "DEADLOCK_DETECTED", + "title": "Signing deadlock risk detected", + "description": "This change may create a signing cycle between Safes and can permanently lock funds. You will not be allowed to proceed forward." + } + ], + "type": "array", + "items": { + "$ref": "#/components/schemas/DeadlockAnalysisResultDto" + } + } + } + }, + "CounterpartyAnalysisDto": { + "type": "object", + "properties": { + "recipient": { + "type": "object", + "description": "Recipient analysis results mapped by address. Contains recipient interaction history and bridge analysis.type: Record
.", + "additionalProperties": { + "$ref": "#/components/schemas/RecipientAnalysisDto" + }, + "example": { + "0x0000000000000000000000000000000000000000": { + "isSafe": true, + "RECIPIENT_INTERACTION": [ + { + "severity": "INFO", + "type": "NEW_RECIPIENT", + "title": "New recipient", + "description": "This is the first time you are interacting with this recipient" + } + ] + } + } + }, + "contract": { + "type": "object", + "description": "Contract analysis results mapped by address. Contains contract verification, interaction history, and delegatecall analysis.type: Record.", + "additionalProperties": { + "$ref": "#/components/schemas/ContractAnalysisDto" + }, + "example": { + "0x0000000000000000000000000000000000000000": { + "CONTRACT_VERIFICATION": [ + { + "severity": "INFO", + "type": "VERIFIED", + "title": "Verified contract", + "description": "This contract has been verified and its source code is available" + } + ] + } + } + }, + "deadlock": { + "type": "object", + "description": "Deadlock analysis results mapped by Safe address. Contains signing deadlock risk findings for owner/threshold management transactions.", + "additionalProperties": { + "$ref": "#/components/schemas/DeadlockAnalysisDto" + }, + "example": { + "0x0000000000000000000000000000000000000000": { + "DEADLOCK": [ + { + "severity": "CRITICAL", + "type": "DEADLOCK_DETECTED", + "title": "Signing deadlock risk detected", + "description": "This change may create a signing cycle between Safes and can permanently lock funds. You will not be allowed to proceed forward." + } + ] + } + } } }, "required": [ - "taskId" + "recipient", + "contract", + "deadlock" ] }, - "RelayErrorResponse": { + "ModuleEnforcementDto": { "type": "object", "properties": { - "code": { + "via": { "type": "string", "enum": [ - "SIMULATION_FAILED", - "INDETERMINATE_SIMULATION" - ], - "description": "Stable identifier of the error condition. The frontend MUST branch on this value (not on `message`, which is informational and may change)." + "module" + ] }, - "message": { + "moduleAddress": { "type": "string", - "description": "Human-readable description of the error. Informational only; do not parse." - }, - "statusCode": { - "type": "number", - "example": 422 + "description": "The module enforcing the policy" } }, "required": [ - "code", - "message", - "statusCode" + "via", + "moduleAddress" ] }, - "RelayTaskStatusReceipt": { + "PolicyContractsDto": { "type": "object", "properties": { - "transactionHash": { + "policyContract": { "type": "string", - "example": "0x4e4bb4493b2183061c3a0106ea96604edcc84f83313dbc0ab718abb1523d1042" + "description": "The policy implementation the guard delegates to" + }, + "safePolicyGuard": { + "type": "string", + "description": "The SafePolicyGuard deployment" } }, "required": [ - "transactionHash" + "policyContract", + "safePolicyGuard" ] }, - "RelayTaskStatus": { + "GuardSlotsDto": { "type": "object", "properties": { - "status": { - "type": "number", - "description": "Relay task status code: 100=Pending, 110=Submitted, 200=Included, 400=Rejected, 500=Reverted", - "enum": [ - 100, - 110, - 200, - 400, - 500 - ], - "example": 200 + "transactionGuard": { + "$ref": "#/components/schemas/PolicyContractsDto" }, - "receipt": { - "description": "On-chain receipt. Only present when status is 200 (Included) or 500 (Reverted)", - "allOf": [ - { - "$ref": "#/components/schemas/RelayTaskStatusReceipt" - } - ] + "moduleGuard": { + "$ref": "#/components/schemas/PolicyContractsDto" } - }, - "required": [ - "status" - ] + } }, - "RelaysRemaining": { + "GuardEnforcementDto": { "type": "object", "properties": { - "remaining": { - "type": "number" + "via": { + "type": "string", + "enum": [ + "guard" + ] }, - "limit": { - "type": "number" + "guards": { + "$ref": "#/components/schemas/GuardSlotsDto" } }, "required": [ - "remaining", - "limit" + "via", + "guards" ] }, - "SafeAppProvider": { + "OffChainEnforcementDto": { "type": "object", "properties": { - "url": { - "type": "string" + "via": { + "type": "string", + "enum": [ + "offchain" + ], + "description": "Nothing on chain enforces the policy, so it is access rather than an audited restriction" }, - "name": { - "type": "string" + "source": { + "type": "string", + "enum": [ + "delegates" + ], + "description": "Where the grant is held" } }, "required": [ - "url", - "name" + "via", + "source" ] }, - "SafeAppAccessControl": { + "NativeTokenMetadataDto": { "type": "object", "properties": { - "type": { + "address": { "type": "string" }, - "value": { - "nullable": true, - "type": "array", - "items": { - "type": "string" - } - } - }, - "required": [ - "type" - ] - }, - "SafeAppSocialProfile": { - "type": "object", - "properties": { - "platform": { + "decimals": { + "type": "number" + }, + "logoUri": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "trusted": { + "type": "boolean", + "description": "Whether the Transaction Service lists the token in one of its imported token lists" + }, + "type": { "type": "string", "enum": [ - "DISCORD", - "GITHUB", - "TWITTER", - "TELEGRAM", - "UNKNOWN" + "NATIVE_TOKEN" ] - }, - "url": { - "type": "string" } }, "required": [ - "platform", - "url" + "address", + "decimals", + "logoUri", + "name", + "symbol", + "trusted", + "type" ] }, - "SafeApp": { + "Erc20TokenMetadataDto": { "type": "object", "properties": { - "id": { + "address": { + "type": "string" + }, + "decimals": { "type": "number" }, - "url": { + "logoUri": { "type": "string" }, "name": { "type": "string" }, - "iconUrl": { - "type": "string", - "nullable": true - }, - "description": { + "symbol": { "type": "string" }, - "chainIds": { - "type": "array", - "items": { - "type": "string" - } - }, - "provider": { - "nullable": true, - "type": "object", - "allOf": [ - { - "$ref": "#/components/schemas/SafeAppProvider" - } - ] - }, - "accessControl": { - "$ref": "#/components/schemas/SafeAppAccessControl" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "features": { - "type": "array", - "items": { - "type": "string" - } + "trusted": { + "type": "boolean", + "description": "Whether the Transaction Service lists the token in one of its imported token lists" }, - "developerWebsite": { + "type": { "type": "string", - "nullable": true - }, - "socialProfiles": { - "type": "array", - "items": { - "$ref": "#/components/schemas/SafeAppSocialProfile" - } - }, - "featured": { - "type": "boolean" + "enum": [ + "ERC20" + ] } }, "required": [ - "id", - "url", + "address", + "decimals", + "logoUri", "name", - "description", - "chainIds", - "accessControl", - "tags", - "features", - "socialProfiles", - "featured" + "symbol", + "trusted", + "type" ] }, - "SafeState": { + "SpendingLimitAllowanceDto": { "type": "object", "properties": { - "address": { - "$ref": "#/components/schemas/AddressInfo" - }, - "chainId": { - "type": "string" - }, - "nonce": { - "type": "number" - }, - "threshold": { - "type": "number" - }, - "owners": { - "type": "array", - "items": { - "$ref": "#/components/schemas/AddressInfo" - } - }, - "implementation": { - "$ref": "#/components/schemas/AddressInfo" - }, - "modules": { - "nullable": true, - "type": "array", - "items": { - "$ref": "#/components/schemas/AddressInfo" - } + "tokenAddress": { + "type": "string", + "description": "The token the limit applies to; zero address for native" }, - "fallbackHandler": { - "nullable": true, - "type": "object", - "allOf": [ + "tokenMetadata": { + "oneOf": [ { - "$ref": "#/components/schemas/AddressInfo" - } - ] - }, - "guard": { - "nullable": true, - "type": "object", - "allOf": [ + "$ref": "#/components/schemas/NativeTokenMetadataDto" + }, { - "$ref": "#/components/schemas/AddressInfo" + "$ref": "#/components/schemas/Erc20TokenMetadataDto" } - ] + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "NATIVE_TOKEN": "#/components/schemas/NativeTokenMetadataDto", + "ERC20": "#/components/schemas/Erc20TokenMetadataDto" + } + }, + "nullable": true, + "description": "Metadata of `tokenAddress`; null when it could not be resolved" }, - "version": { + "amount": { "type": "string", - "nullable": true + "description": "Per-window ceiling, in base units" }, - "implementationVersionState": { + "spent": { "type": "string", - "enum": [ - "UP_TO_DATE", - "OUTDATED", - "UNKNOWN" - ] + "description": "Spent in the current window, in base units" }, - "collectiblesTag": { - "type": "string", - "nullable": true + "resetPeriodMinutes": { + "type": "number", + "description": "Window length in minutes; 0 never resets" }, - "txQueuedTag": { - "type": "string", - "nullable": true + "resetsAtMinute": { + "type": "number", + "nullable": true, + "description": "Minutes since the epoch of the next reset, the unit the module counts windows in; null when it never resets" }, - "txHistoryTag": { - "type": "string", - "nullable": true + "resetBoundaryIsExact": { + "type": "boolean", + "description": "False when the reset boundary could not be recovered exactly, so `resetsAtMinute` may be up to one period out. `amount` is unaffected." }, - "messagesTag": { - "type": "string", - "nullable": true + "isDelegateActive": { + "type": "boolean", + "description": "False when the spender's delegate registration was removed: nothing is spendable now, but the allowance returns to effect if the delegate is re-added" + }, + "createdAt": { + "type": "number", + "description": "Unix seconds this allowance was (re-)established" + }, + "updatedAt": { + "type": "number", + "description": "Unix seconds of the last event that changed this allowance" } }, "required": [ - "address", - "chainId", - "nonce", - "threshold", - "owners", - "implementation", - "implementationVersionState" + "tokenAddress", + "tokenMetadata", + "amount", + "spent", + "resetPeriodMinutes", + "resetsAtMinute", + "resetBoundaryIsExact", + "isDelegateActive", + "createdAt", + "updatedAt" ] }, - "SafeNonces": { + "SpendingLimitSpenderDto": { "type": "object", "properties": { - "currentNonce": { - "type": "number" + "spender": { + "type": "string", + "description": "Name resolved by the client, never carried here" }, - "recommendedNonce": { - "type": "number" + "isActive": { + "type": "boolean", + "description": "False when the spender is deregistered: nothing is spendable now, but the allowances survive and return if it is re-added" + }, + "allowances": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SpendingLimitAllowanceDto" + } } }, "required": [ - "currentNonce", - "recommendedNonce" + "spender", + "isActive", + "allowances" ] }, - "SafeOverview": { + "SpendingLimitPolicyDataDto": { "type": "object", "properties": { - "address": { - "$ref": "#/components/schemas/AddressInfo" - }, - "chainId": { - "type": "string" + "module": { + "type": "string", + "description": "The allowance module holding this state" }, - "threshold": { - "type": "number" - }, - "owners": { + "spenders": { "type": "array", "items": { - "$ref": "#/components/schemas/AddressInfo" + "$ref": "#/components/schemas/SpendingLimitSpenderDto" } - }, - "fiatTotal": { - "type": "string" - }, - "queued": { - "type": "number" - }, - "awaitingConfirmation": { - "type": "number", - "nullable": true } }, "required": [ - "address", - "chainId", - "threshold", - "owners", - "fiatTotal", - "queued" + "module", + "spenders" ] }, - "SingleRecipientAnalysisResultDto": { + "ProposerGrantDto": { "type": "object", "properties": { - "severity": { - "type": "string", - "description": "Severity level indicating the importance and risk", - "enum": [ - "OK", - "INFO", - "WARN", - "CRITICAL" - ] - }, - "type": { - "type": "string", - "description": "Recipient interaction status code", - "enum": [ - "NEW_RECIPIENT", - "RECURRING_RECIPIENT", - "LOW_ACTIVITY", - "FAILED" - ], - "example": "NEW_RECIPIENT" - }, - "title": { - "type": "string", - "description": "User-facing title of the finding" - }, - "description": { + "delegator": { "type": "string", - "description": "Detailed description explaining the finding and its implications" + "description": "The owner that granted the proposer" }, - "error": { + "label": { "type": "string", - "description": "Error message for failed analysis" + "description": "The label this owner gave the proposer; empty when unlabelled" } }, "required": [ - "severity", - "type", - "title", - "description" + "delegator", + "label" ] }, - "SingleRecipientAnalysisDto": { + "ProposerDto": { "type": "object", "properties": { - "RECIPIENT_INTERACTION": { - "description": "Analysis results related to recipient interaction history. Shows whether this is a new or recurring recipient.", - "example": [ - { - "severity": "INFO", - "type": "NEW_RECIPIENT", - "title": "New recipient", - "description": "This is the first time you are interacting with this recipient." - } - ], + "proposer": { + "type": "string", + "description": "The address allowed to propose transactions" + }, + "delegatedBy": { + "description": "The owners that granted it, each with the label they gave. The label is stored per grant, so two owners can label the same proposer differently", "type": "array", "items": { - "$ref": "#/components/schemas/SingleRecipientAnalysisResultDto" + "$ref": "#/components/schemas/ProposerGrantDto" } - }, - "RECIPIENT_ACTIVITY": { - "description": "Analysis results related to recipient activity. Shows whether this is a low activity recipient. (Available only for Safes)", - "example": [ - { - "severity": "WARN", - "type": "LOW_ACTIVITY", - "title": "Low activity recipient", - "description": "This address has few transactions." - } - ], + } + }, + "required": [ + "proposer", + "delegatedBy" + ] + }, + "ProposerPolicyDataDto": { + "type": "object", + "properties": { + "proposers": { "type": "array", "items": { - "$ref": "#/components/schemas/SingleRecipientAnalysisResultDto" + "$ref": "#/components/schemas/ProposerDto" } + } + }, + "required": [ + "proposers" + ] + }, + "SafeRefDto": { + "type": "object", + "properties": { + "chainId": { + "type": "string" }, - "isSafe": { - "type": "boolean", - "description": "Indicates whether the analyzed recipient address is a Safe.", - "example": false + "address": { + "type": "string" } }, "required": [ - "RECIPIENT_INTERACTION", - "isSafe" + "chainId", + "address" ] }, - "CounterpartyAnalysisRequestDto": { + "ActivePolicyDto": { "type": "object", "properties": { - "to": { + "type": { "type": "string", - "description": "Recipient address of the transaction." + "enum": [ + "spending-limit", + "recovery", + "proposer", + "erc20-transfer", + "cosigner", + "allow", + "native-transfer", + "deny" + ] }, - "value": { - "type": "string", - "description": "Amount to send with the transaction." + "enforcement": { + "oneOf": [ + { + "$ref": "#/components/schemas/ModuleEnforcementDto" + }, + { + "$ref": "#/components/schemas/GuardEnforcementDto" + }, + { + "$ref": "#/components/schemas/OffChainEnforcementDto" + } + ], + "discriminator": { + "propertyName": "via", + "mapping": { + "module": "#/components/schemas/ModuleEnforcementDto", + "guard": "#/components/schemas/GuardEnforcementDto", + "offchain": "#/components/schemas/OffChainEnforcementDto" + } + } + }, + "enabled": { + "type": "boolean", + "description": "False when the policy is configured but not enforced" }, "data": { - "type": "string", - "description": "Hex-encoded data payload for the transaction." + "oneOf": [ + { + "$ref": "#/components/schemas/SpendingLimitPolicyDataDto" + }, + { + "$ref": "#/components/schemas/ProposerPolicyDataDto" + } + ] }, - "operation": { - "type": "number", - "enum": [ - 0, - 1 - ], - "description": "Operation type: 0 for CALL, 1 for DELEGATECALL." + "safe": { + "description": "The Safe the policy is in effect on", + "allOf": [ + { + "$ref": "#/components/schemas/SafeRefDto" + } + ] } }, "required": [ - "to", - "value", + "type", + "enforcement", + "enabled", "data", - "operation" + "safe" ] }, - "RecipientResultDto": { + "EnableModuleChangeDto": { "type": "object", "properties": { - "severity": { + "kind": { "type": "string", - "description": "Severity level indicating the importance and risk", "enum": [ - "OK", - "INFO", - "WARN", - "CRITICAL" + "enable-module" ] - }, - "type": { + } + }, + "required": [ + "kind" + ] + }, + "AddDelegateChangeDto": { + "type": "object", + "properties": { + "kind": { "type": "string", - "description": "Bridge compatibility status code", "enum": [ - "NEW_RECIPIENT", - "RECURRING_RECIPIENT", - "LOW_ACTIVITY", - "INCOMPATIBLE_SAFE", - "MISSING_OWNERSHIP", - "UNSUPPORTED_NETWORK", - "DIFFERENT_SAFE_SETUP", - "FAILED" - ], - "example": "MISSING_OWNERSHIP" + "add-delegate" + ] }, - "title": { + "delegate": { "type": "string", - "description": "User-facing title of the finding" - }, - "description": { + "description": "The address being added as a delegate in AllowanceModule contract" + } + }, + "required": [ + "kind", + "delegate" + ] + }, + "RemoveDelegateChangeDto": { + "type": "object", + "properties": { + "kind": { "type": "string", - "description": "Detailed description explaining the finding and its implications" + "enum": [ + "remove-delegate" + ] }, - "error": { + "delegate": { "type": "string", - "description": "Error message for failed analysis" + "description": "The delegate being removed" }, - "targetChainId": { - "type": "string", - "description": "Target chain ID for bridge operations. Only present for BridgeStatus." + "removeAllowances": { + "type": "boolean", + "description": "Whether the delegate's allowances are deleted along with it" } }, "required": [ - "severity", - "type", - "title", - "description" + "kind", + "delegate", + "removeAllowances" ] }, - "RecipientAnalysisDto": { + "SetAllowanceChangeDto": { "type": "object", "properties": { - "isSafe": { - "type": "boolean", - "description": "Indicates whether the analyzed recipient address is a Safe.", - "example": true + "kind": { + "type": "string", + "enum": [ + "set-allowance" + ] }, - "RECIPIENT_INTERACTION": { - "description": "Analysis results related to recipient interaction history. Shows whether this is a new or recurring recipient.", - "example": [ - { - "severity": "INFO", - "type": "NEW_RECIPIENT", - "title": "New recipient", - "description": "This is the first time you are interacting with this recipient." - } - ], - "type": "array", - "items": { - "$ref": "#/components/schemas/RecipientResultDto" - } + "delegate": { + "type": "string" }, - "RECIPIENT_ACTIVITY": { - "description": "Analysis results related to recipient activity frequency. Shows whether this is a low activity recipient.", - "example": [ + "token": { + "type": "string", + "description": "The token the limit applies to; zero address for native" + }, + "tokenMetadata": { + "oneOf": [ { - "severity": "WARN", - "type": "LOW_ACTIVITY", - "title": "Low activity recipient", - "description": "This address has few transactions." + "$ref": "#/components/schemas/NativeTokenMetadataDto" + }, + { + "$ref": "#/components/schemas/Erc20TokenMetadataDto" } ], - "type": "array", - "items": { - "$ref": "#/components/schemas/RecipientResultDto" - } - }, - "BRIDGE": { - "description": "Analysis results for cross-chain bridge operations. Identifies compatibility issues, ownership problems, or unsupported networks.", - "example": [ - { - "severity": "WARN", - "type": "MISSING_OWNERSHIP", - "title": "No ownership on target chain", - "description": "You do not have ownership of a Safe on the target chain.", - "targetChainId": "137" + "discriminator": { + "propertyName": "type", + "mapping": { + "NATIVE_TOKEN": "#/components/schemas/NativeTokenMetadataDto", + "ERC20": "#/components/schemas/Erc20TokenMetadataDto" } - ], - "type": "array", - "items": { - "$ref": "#/components/schemas/RecipientResultDto" - } + }, + "nullable": true, + "description": "Metadata of `token`; null when it could not be resolved" + }, + "amount": { + "type": "string", + "description": "Per-window ceiling, in base units" + }, + "resetPeriodMinutes": { + "type": "number", + "description": "Window length in minutes; 0 never resets" } }, "required": [ - "isSafe" + "kind", + "delegate", + "token", + "tokenMetadata", + "amount", + "resetPeriodMinutes" ] }, - "ContractAnalysisResultDto": { + "ResetAllowanceChangeDto": { "type": "object", "properties": { - "severity": { + "kind": { "type": "string", - "description": "Severity level indicating the importance and risk", "enum": [ - "OK", - "INFO", - "WARN", - "CRITICAL" + "reset-allowance" ] }, - "type": { + "delegate": { + "type": "string" + }, + "token": { + "type": "string" + }, + "tokenMetadata": { + "oneOf": [ + { + "$ref": "#/components/schemas/NativeTokenMetadataDto" + }, + { + "$ref": "#/components/schemas/Erc20TokenMetadataDto" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "NATIVE_TOKEN": "#/components/schemas/NativeTokenMetadataDto", + "ERC20": "#/components/schemas/Erc20TokenMetadataDto" + } + }, + "nullable": true, + "description": "Metadata of `token`; null when it could not be resolved" + } + }, + "required": [ + "kind", + "delegate", + "token", + "tokenMetadata" + ] + }, + "DeleteAllowanceChangeDto": { + "type": "object", + "properties": { + "kind": { "type": "string", - "description": "Contract verification status code", "enum": [ - "VERIFIED", - "NOT_VERIFIED", - "NOT_VERIFIED_BY_SAFE", - "VERIFICATION_UNAVAILABLE", - "NEW_CONTRACT", - "KNOWN_CONTRACT", - "UNEXPECTED_DELEGATECALL", - "UNOFFICIAL_FALLBACK_HANDLER", - "FAILED" - ], - "example": "VERIFIED" + "delete-allowance" + ] }, - "title": { - "type": "string", - "description": "User-facing title of the finding" + "delegate": { + "type": "string" }, - "description": { - "type": "string", - "description": "Detailed description explaining the finding and its implications" + "token": { + "type": "string" }, - "error": { - "type": "string", - "description": "Error message for failed analysis" + "tokenMetadata": { + "oneOf": [ + { + "$ref": "#/components/schemas/NativeTokenMetadataDto" + }, + { + "$ref": "#/components/schemas/Erc20TokenMetadataDto" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "NATIVE_TOKEN": "#/components/schemas/NativeTokenMetadataDto", + "ERC20": "#/components/schemas/Erc20TokenMetadataDto" + } + }, + "nullable": true, + "description": "Metadata of `token`; null when it could not be resolved" } }, "required": [ - "severity", - "type", - "title", - "description" + "kind", + "delegate", + "token", + "tokenMetadata" ] }, - "FallbackHandlerInfoDto": { + "PendingSpendingLimitDataDto": { "type": "object", "properties": { - "address": { - "type": "string", - "description": "Address of the fallback handler contract" - }, - "name": { + "module": { "type": "string", - "description": "Name of the fallback handler contract" + "description": "The AllowanceModule deployment holding this state" }, - "logoUrl": { - "type": "string", - "description": "Logo URL for the fallback handler contract" + "changes": { + "type": "array", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/EnableModuleChangeDto" + }, + { + "$ref": "#/components/schemas/AddDelegateChangeDto" + }, + { + "$ref": "#/components/schemas/RemoveDelegateChangeDto" + }, + { + "$ref": "#/components/schemas/SetAllowanceChangeDto" + }, + { + "$ref": "#/components/schemas/ResetAllowanceChangeDto" + }, + { + "$ref": "#/components/schemas/DeleteAllowanceChangeDto" + } + ], + "discriminator": { + "propertyName": "kind", + "mapping": { + "enable-module": "#/components/schemas/EnableModuleChangeDto", + "add-delegate": "#/components/schemas/AddDelegateChangeDto", + "remove-delegate": "#/components/schemas/RemoveDelegateChangeDto", + "set-allowance": "#/components/schemas/SetAllowanceChangeDto", + "reset-allowance": "#/components/schemas/ResetAllowanceChangeDto", + "delete-allowance": "#/components/schemas/DeleteAllowanceChangeDto" + } + } + }, + "description": "The AllowanceModule calls this transaction decodes to" } }, "required": [ - "address" + "module", + "changes" ] }, - "FallbackHandlerAnalysisResultDto": { + "PendingPolicyDto": { "type": "object", "properties": { - "severity": { + "kind": { "type": "string", - "description": "Severity level indicating the importance and risk", "enum": [ - "OK", - "INFO", - "WARN", - "CRITICAL" + "queued-transaction" ] }, "type": { "type": "string", - "description": "Status code for unofficial fallback handler", "enum": [ - "UNOFFICIAL_FALLBACK_HANDLER" - ], - "example": "VERIFIED" + "spending-limit" + ] }, - "title": { - "type": "string", - "description": "User-facing title of the finding" + "enforcement": { + "$ref": "#/components/schemas/ModuleEnforcementDto" }, - "description": { + "safeTxHash": { "type": "string", - "description": "Detailed description explaining the finding and its implications" + "description": "The queued transaction this change was found in" }, - "error": { - "type": "string", - "description": "Error message for failed analysis" + "nonce": { + "type": "number" }, - "fallbackHandler": { - "description": "Information about the fallback handler", + "confirmations": { + "type": "number" + }, + "confirmationsRequired": { + "type": "number" + }, + "proposedAt": { + "type": "number", + "description": "Unix seconds the transaction was proposed at" + }, + "data": { + "$ref": "#/components/schemas/PendingSpendingLimitDataDto" + }, + "safe": { + "description": "The Safe the change is queued on", "allOf": [ { - "$ref": "#/components/schemas/FallbackHandlerInfoDto" + "$ref": "#/components/schemas/SafeRefDto" } ] } }, "required": [ - "severity", + "kind", "type", - "title", - "description" + "enforcement", + "safeTxHash", + "nonce", + "confirmations", + "confirmationsRequired", + "proposedAt", + "data", + "safe" ] }, - "ContractAnalysisDto": { + "SurveyOptionDto": { "type": "object", "properties": { - "logoUrl": { - "type": "string", - "description": "Logo URL for the contract", - "example": "https://example.com/logo.png" + "key": { + "type": "string" }, - "name": { + "label": { + "type": "string" + }, + "description": { + "type": "string" + }, + "icon": { + "type": "string" + } + }, + "required": [ + "key", + "label" + ] + }, + "SurveyPageDto": { + "type": "object", + "properties": { + "id": { + "type": "string" + }, + "title": { + "type": "string" + }, + "subtitle": { "type": "string", - "description": "Name of the contract", - "example": "Uniswap V3 Router" + "nullable": true }, - "CONTRACT_VERIFICATION": { - "description": "Analysis results for contract verification status. Shows whether contracts are verified and source code is available.", - "example": [ - { - "severity": "INFO", - "type": "VERIFIED", - "title": "Verified contract", - "description": "This contract has been verified and its source code is available" - } - ], - "type": "array", - "items": { - "$ref": "#/components/schemas/ContractAnalysisResultDto" - } + "multiSelect": { + "type": "boolean" }, - "CONTRACT_INTERACTION": { - "description": "Analysis results related to contract interaction history. Shows whether this is a new or previously interacted contract.", - "example": [ - { - "severity": "INFO", - "type": "NEW_CONTRACT", - "title": "New contract", - "description": "This is the first time you are interacting with this contract" - } - ], + "options": { "type": "array", "items": { - "$ref": "#/components/schemas/ContractAnalysisResultDto" + "$ref": "#/components/schemas/SurveyOptionDto" } - }, - "DELEGATECALL": { - "description": "Analysis results for delegatecall operations. Identifies unexpected or potentially dangerous delegate calls.", - "example": [ - { - "severity": "CRITICAL", - "type": "UNEXPECTED_DELEGATECALL", - "title": "Unexpected delegatecall", - "description": "An unexpected delegatecall operation was detected that could be dangerous" - } - ], - "type": "array", - "items": { - "$ref": "#/components/schemas/ContractAnalysisResultDto" - } - }, - "FALLBACK_HANDLER": { - "description": "Analysis results for setFallbackHandler operations. Identifies untrusted or unofficial fallback handlers in the transactions.", - "example": [ - { - "severity": "WARN", - "type": "UNOFFICIAL_FALLBACK_HANDLER", - "title": "Unofficial fallback handler", - "description": "Verify the fallback handler is trusted and secure before proceeding.", - "fallbackHandler": { - "address": "0x123", - "name": "CompatibilityFallbackHandler", - "logoUrl": "https://example.com/logo.png" - } - } - ], + } + }, + "required": [ + "id", + "title", + "subtitle", + "multiSelect", + "options" + ] + }, + "SurveyContentDto": { + "type": "object", + "properties": { + "pages": { "type": "array", "items": { - "$ref": "#/components/schemas/FallbackHandlerAnalysisResultDto" + "$ref": "#/components/schemas/SurveyPageDto" } } - } + }, + "required": [ + "pages" + ] }, - "DeadlockAnalysisResultDto": { + "SurveyDto": { "type": "object", "properties": { - "severity": { - "type": "string", - "description": "Severity level indicating the importance and risk", - "enum": [ - "OK", - "INFO", - "WARN", - "CRITICAL" - ] + "id": { + "type": "number" }, - "type": { - "type": "string", - "description": "Deadlock analysis status code", - "enum": [ - "DEADLOCK_DETECTED", - "NESTED_SAFE_WARNING", - "FAILED" - ], - "example": "DEADLOCK_DETECTED" + "slug": { + "type": "string" + }, + "version": { + "type": "number" }, "title": { - "type": "string", - "description": "User-facing title of the finding" + "type": "string" }, - "description": { + "subtitle": { "type": "string", - "description": "Detailed description explaining the finding and its implications" + "nullable": true }, - "error": { - "type": "string", - "description": "Error message for failed analysis" + "surveyContent": { + "$ref": "#/components/schemas/SurveyContentDto" } }, "required": [ - "severity", - "type", + "id", + "slug", + "version", "title", - "description" + "subtitle", + "surveyContent" ] }, - "DeadlockAnalysisDto": { + "SpaceSurveyResponseDto": { "type": "object", "properties": { - "DEADLOCK": { - "description": "Deadlock analysis findings. Identifies signing deadlock risks in nested Safe configurations.", - "example": [ + "surveyVersion": { + "type": "number" + }, + "selections": { + "type": "object", + "additionalProperties": { + "type": "array", + "items": { + "type": "string" + } + }, + "description": "Map from page id → selected option keys" + }, + "submittedAt": { + "format": "date-time", + "type": "string" + }, + "updatedAt": { + "format": "date-time", + "type": "string" + }, + "answeredByUserId": { + "type": "number", + "nullable": true + } + }, + "required": [ + "surveyVersion", + "selections", + "submittedAt", + "updatedAt", + "answeredByUserId" + ] + }, + "SurveyStateDto": { + "type": "object", + "properties": { + "survey": { + "$ref": "#/components/schemas/SurveyDto" + }, + "surveyResponse": { + "nullable": true, + "type": "object", + "allOf": [ { - "severity": "CRITICAL", - "type": "DEADLOCK_DETECTED", - "title": "Signing deadlock risk detected", - "description": "This change may create a signing cycle between Safes and can permanently lock funds. You will not be allowed to proceed forward." + "$ref": "#/components/schemas/SpaceSurveyResponseDto" } - ], - "type": "array", - "items": { - "$ref": "#/components/schemas/DeadlockAnalysisResultDto" - } + ] } - } + }, + "required": [ + "survey", + "surveyResponse" + ] }, - "CounterpartyAnalysisDto": { + "SubmitSurveyResponseDto": { "type": "object", "properties": { - "recipient": { + "selections": { "type": "object", - "description": "Recipient analysis results mapped by address. Contains recipient interaction history and bridge analysis.type: Record.", "additionalProperties": { - "$ref": "#/components/schemas/RecipientAnalysisDto" + "type": "array", + "items": { + "type": "string" + } }, + "description": "Map from page id → selected option keys", "example": { - "0x0000000000000000000000000000000000000000": { - "isSafe": true, - "RECIPIENT_INTERACTION": [ - { - "severity": "INFO", - "type": "NEW_RECIPIENT", - "title": "New recipient", - "description": "This is the first time you are interacting with this recipient" - } - ] - } + "use_cases": [ + "run_payments", + "hold_assets" + ] } + } + }, + "required": [ + "selections" + ] + }, + "SurveyResponseResultDto": { + "type": "object", + "properties": { + "id": { + "type": "number" }, - "contract": { + "spaceUuid": { + "type": "string", + "description": "Space UUID" + }, + "surveySlug": { + "type": "string" + }, + "surveyVersion": { + "type": "number" + }, + "selections": { "type": "object", - "description": "Contract analysis results mapped by address. Contains contract verification, interaction history, and delegatecall analysis.type: Record.", "additionalProperties": { - "$ref": "#/components/schemas/ContractAnalysisDto" - }, - "example": { - "0x0000000000000000000000000000000000000000": { - "CONTRACT_VERIFICATION": [ - { - "severity": "INFO", - "type": "VERIFIED", - "title": "Verified contract", - "description": "This contract has been verified and its source code is available" - } - ] + "type": "array", + "items": { + "type": "string" } } }, - "deadlock": { - "type": "object", - "description": "Deadlock analysis results mapped by Safe address. Contains signing deadlock risk findings for owner/threshold management transactions.", - "additionalProperties": { - "$ref": "#/components/schemas/DeadlockAnalysisDto" - }, - "example": { - "0x0000000000000000000000000000000000000000": { - "DEADLOCK": [ - { - "severity": "CRITICAL", - "type": "DEADLOCK_DETECTED", - "title": "Signing deadlock risk detected", - "description": "This change may create a signing cycle between Safes and can permanently lock funds. You will not be allowed to proceed forward." - } - ] - } + "submittedAt": { + "format": "date-time", + "type": "string" + }, + "updatedAt": { + "format": "date-time", + "type": "string" + }, + "answeredByUserId": { + "type": "number", + "nullable": true + } + }, + "required": [ + "id", + "spaceUuid", + "surveySlug", + "surveyVersion", + "selections", + "submittedAt", + "updatedAt", + "answeredByUserId" + ] + }, + "FeatureKey": { + "type": "string", + "enum": [ + "safe_seats", + "copilot_scans", + "sponsored_transactions", + "policies" + ], + "description": "Feature key from the entitlements catalog." + }, + "BinaryEntitlement": { + "type": "object", + "properties": { + "feature": { + "description": "Feature key from the entitlements catalog.", + "allOf": [ + { + "$ref": "#/components/schemas/FeatureKey" + } + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the plan grants the feature at all. A metered feature reports its quota and usage even when this is false." + }, + "type": { + "type": "string", + "enum": [ + "binary" + ] + } + }, + "required": [ + "feature", + "enabled", + "type" + ] + }, + "ValueEntitlement": { + "type": "object", + "properties": { + "feature": { + "description": "Feature key from the entitlements catalog.", + "allOf": [ + { + "$ref": "#/components/schemas/FeatureKey" + } + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the plan grants the feature at all. A metered feature reports its quota and usage even when this is false." + }, + "type": { + "type": "string", + "enum": [ + "value" + ] + }, + "value": { + "type": "string", + "nullable": true + } + }, + "required": [ + "feature", + "enabled", + "type", + "value" + ] + }, + "MeteredEntitlement": { + "type": "object", + "properties": { + "feature": { + "description": "Feature key from the entitlements catalog.", + "allOf": [ + { + "$ref": "#/components/schemas/FeatureKey" + } + ] + }, + "enabled": { + "type": "boolean", + "description": "Whether the plan grants the feature at all. A metered feature reports its quota and usage even when this is false." + }, + "type": { + "type": "string", + "enum": [ + "metered" + ] + }, + "quota": { + "type": "number", + "nullable": true, + "description": "The plan's quota, never inflated to match usage; null means unlimited." + }, + "used": { + "type": "number", + "description": "May legally exceed `quota`." + }, + "resetsAt": { + "format": "date-time", + "type": "string", + "nullable": true, + "description": "Null for stock-type features (seats) that have no reset window." + } + }, + "required": [ + "feature", + "enabled", + "type", + "quota", + "used", + "resetsAt" + ] + }, + "EntitlementsPlanStatus": { + "type": "string", + "enum": [ + "active", + "trialing" + ], + "description": "Status of the subscription the plan comes from" + }, + "EntitlementsPlan": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "Plan identifier in the billing service" + }, + "name": { + "type": "string", + "nullable": true + }, + "cycleEndsAt": { + "format": "date-time", + "type": "string", + "nullable": true, + "description": "End of the current billing cycle" + }, + "status": { + "description": "Status of the subscription the plan comes from", + "allOf": [ + { + "$ref": "#/components/schemas/EntitlementsPlanStatus" + } + ] + } + }, + "required": [ + "id", + "name", + "cycleEndsAt", + "status" + ] + }, + "EntitlementsResponse": { + "type": "object", + "properties": { + "plan": { + "nullable": true, + "description": "Null when the workspace has no active subscription.", + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/EntitlementsPlan" + } + ] + }, + "entitlements": { + "type": "array", + "description": "One entry per catalog feature. Which fields an entry carries is decided by `type`: a metered one always carries quota, usage and its reset window, and the others never do.", + "items": { + "oneOf": [ + { + "$ref": "#/components/schemas/BinaryEntitlement" + }, + { + "$ref": "#/components/schemas/ValueEntitlement" + }, + { + "$ref": "#/components/schemas/MeteredEntitlement" + } + ], + "discriminator": { + "propertyName": "type", + "mapping": { + "binary": "#/components/schemas/BinaryEntitlement", + "value": "#/components/schemas/ValueEntitlement", + "metered": "#/components/schemas/MeteredEntitlement" + } + } + } + } + }, + "required": [ + "plan", + "entitlements" + ] + }, + "SpaceRelayDto": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "to": { + "type": "string" + }, + "data": { + "type": "string" + }, + "safeTxHash": { + "type": "string", + "description": "Safe transaction hash, forwarded to the relay provider for traceability. Not verified against the calldata on this route." + }, + "acceptUnverifiedSimulation": { + "type": "boolean", + "description": "Set to true to proceed with the relay when a previous attempt returned INDETERMINATE_SIMULATION. The user has acknowledged the simulation could not be completed and accepts the risk." + } + }, + "required": [ + "version", + "to", + "data" + ] + }, + "Relay": { + "type": "object", + "properties": { + "taskId": { + "type": "string" + } + }, + "required": [ + "taskId" + ] + }, + "GasPaymentOptionUnavailableResponse": { + "type": "object", + "properties": { + "code": { + "type": "string", + "enum": [ + "GAS_PAYMENT_OPTION_UNAVAILABLE" + ] + }, + "message": { + "type": "string", + "description": "Human-readable description of the error. Informational only; do not parse." + }, + "statusCode": { + "type": "number", + "example": 409 + }, + "requested": { + "type": "string", + "enum": [ + "FREE_DAILY_LIMIT", + "SUBSCRIPTION", + "PAY_FROM_SAFE", + "NO_FEE_CAMPAIGN" + ], + "description": "The gas payment option the request needed." + }, + "reason": { + "type": "string", + "enum": [ + "NOT_LISTED", + "NO_RELAYER", + "NOT_A_WORKSPACE_SAFE", + "REFUNDING_TRANSACTION" + ], + "description": "NOT_LISTED: the chain does not list the option. NO_RELAYER: the chain has no relayer. NOT_A_WORKSPACE_SAFE: the Safe is not one the workspace holds. REFUNDING_TRANSACTION: the transaction would refund gas (`gasPrice` > 0)." + }, + "available": { + "type": "array", + "description": "The options the chain lists; empty without a relayer.", + "items": { + "type": "string", + "enum": [ + "FREE_DAILY_LIMIT", + "SUBSCRIPTION", + "PAY_FROM_SAFE", + "NO_FEE_CAMPAIGN" + ] + } + } + }, + "required": [ + "code", + "message", + "statusCode", + "requested", + "reason", + "available" + ] + }, + "SafeList": { + "type": "object", + "properties": { + "safes": { + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "safes" + ] + }, + "RelayDto": { + "type": "object", + "properties": { + "version": { + "type": "string" + }, + "to": { + "type": "string" + }, + "data": { + "type": "string" + }, + "gasLimit": { + "type": "string", + "nullable": true, + "description": "Accepted for backward compatibility and validation; not forwarded to the relay provider." + }, + "safeTxHash": { + "type": "string", + "description": "Safe transaction hash for relay-fee eligibility check" + }, + "acceptUnverifiedSimulation": { + "type": "boolean", + "description": "Set to true to proceed with the relay when a previous attempt returned INDETERMINATE_SIMULATION. The user has acknowledged the simulation could not be completed and accepts the risk." + } + }, + "required": [ + "version", + "to", + "data" + ] + }, + "RelayErrorResponse": { + "type": "object", + "properties": { + "code": { + "type": "string", + "enum": [ + "SIMULATION_FAILED", + "INDETERMINATE_SIMULATION" + ], + "description": "Stable identifier of the error condition. The frontend MUST branch on this value (not on `message`, which is informational and may change)." + }, + "message": { + "type": "string", + "description": "Human-readable description of the error. Informational only; do not parse." + }, + "statusCode": { + "type": "number", + "example": 422 + } + }, + "required": [ + "code", + "message", + "statusCode" + ] + }, + "RelayTaskStatusReceipt": { + "type": "object", + "properties": { + "transactionHash": { + "type": "string", + "example": "0x4e4bb4493b2183061c3a0106ea96604edcc84f83313dbc0ab718abb1523d1042" + } + }, + "required": [ + "transactionHash" + ] + }, + "RelayTaskStatus": { + "type": "object", + "properties": { + "status": { + "type": "number", + "description": "Relay task status code: 100=Pending, 110=Submitted, 200=Included, 400=Rejected, 500=Reverted", + "enum": [ + 100, + 110, + 200, + 400, + 500 + ], + "example": 200 + }, + "receipt": { + "description": "On-chain receipt. Only present when status is 200 (Included) or 500 (Reverted)", + "allOf": [ + { + "$ref": "#/components/schemas/RelayTaskStatusReceipt" + } + ] + } + }, + "required": [ + "status" + ] + }, + "RelaysRemaining": { + "type": "object", + "properties": { + "remaining": { + "type": "number" + }, + "limit": { + "type": "number" + } + }, + "required": [ + "remaining", + "limit" + ] + }, + "SafeAppProvider": { + "type": "object", + "properties": { + "url": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "url", + "name" + ] + }, + "SafeAppAccessControl": { + "type": "object", + "properties": { + "type": { + "type": "string" + }, + "value": { + "nullable": true, + "type": "array", + "items": { + "type": "string" + } + } + }, + "required": [ + "type" + ] + }, + "SafeAppSocialProfile": { + "type": "object", + "properties": { + "platform": { + "type": "string", + "enum": [ + "DISCORD", + "GITHUB", + "TWITTER", + "TELEGRAM", + "UNKNOWN" + ] + }, + "url": { + "type": "string" + } + }, + "required": [ + "platform", + "url" + ] + }, + "SafeApp": { + "type": "object", + "properties": { + "id": { + "type": "number" + }, + "url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "iconUrl": { + "type": "string", + "nullable": true + }, + "description": { + "type": "string" + }, + "chainIds": { + "type": "array", + "items": { + "type": "string" + } + }, + "provider": { + "nullable": true, + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/SafeAppProvider" + } + ] + }, + "accessControl": { + "$ref": "#/components/schemas/SafeAppAccessControl" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "features": { + "type": "array", + "items": { + "type": "string" + } + }, + "developerWebsite": { + "type": "string", + "nullable": true + }, + "socialProfiles": { + "type": "array", + "items": { + "$ref": "#/components/schemas/SafeAppSocialProfile" + } + }, + "featured": { + "type": "boolean" + } + }, + "required": [ + "id", + "url", + "name", + "description", + "chainIds", + "accessControl", + "tags", + "features", + "socialProfiles", + "featured" + ] + }, + "SafeState": { + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/AddressInfo" + }, + "chainId": { + "type": "string" + }, + "nonce": { + "type": "number" + }, + "threshold": { + "type": "number" + }, + "owners": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddressInfo" + } + }, + "implementation": { + "$ref": "#/components/schemas/AddressInfo" + }, + "modules": { + "nullable": true, + "type": "array", + "items": { + "$ref": "#/components/schemas/AddressInfo" + } + }, + "fallbackHandler": { + "nullable": true, + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AddressInfo" + } + ] + }, + "guard": { + "nullable": true, + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/AddressInfo" + } + ] + }, + "version": { + "type": "string", + "nullable": true + }, + "implementationVersionState": { + "type": "string", + "enum": [ + "UP_TO_DATE", + "OUTDATED", + "UNKNOWN" + ] + }, + "collectiblesTag": { + "type": "string", + "nullable": true + }, + "txQueuedTag": { + "type": "string", + "nullable": true + }, + "txHistoryTag": { + "type": "string", + "nullable": true + }, + "messagesTag": { + "type": "string", + "nullable": true + } + }, + "required": [ + "address", + "chainId", + "nonce", + "threshold", + "owners", + "implementation", + "implementationVersionState" + ] + }, + "SafeNonces": { + "type": "object", + "properties": { + "currentNonce": { + "type": "number" + }, + "recommendedNonce": { + "type": "number" + } + }, + "required": [ + "currentNonce", + "recommendedNonce" + ] + }, + "SafeOverview": { + "type": "object", + "properties": { + "address": { + "$ref": "#/components/schemas/AddressInfo" + }, + "chainId": { + "type": "string" + }, + "threshold": { + "type": "number" + }, + "owners": { + "type": "array", + "items": { + "$ref": "#/components/schemas/AddressInfo" } + }, + "fiatTotal": { + "type": "string" + }, + "queued": { + "type": "number" + }, + "awaitingConfirmation": { + "type": "number", + "nullable": true } }, "required": [ - "recipient", - "contract", - "deadlock" + "address", + "chainId", + "threshold", + "owners", + "fiatTotal", + "queued" ] }, "ThreatAnalysisRequestDto": { @@ -14277,6 +16286,7 @@ } }, "rejectors": { + "deprecated": true, "type": "array", "items": { "$ref": "#/components/schemas/AddressInfo" @@ -14355,25 +16365,6 @@ "address" ] }, - "SafeAppInfo": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "url": { - "type": "string" - }, - "logoUri": { - "type": "string", - "nullable": true - } - }, - "required": [ - "name", - "url" - ] - }, "TransactionDetails": { "type": "object", "properties": { @@ -15084,6 +17075,64 @@ "results" ] }, + "NestedTransactionDto": { + "type": "object", + "properties": { + "to": { + "type": "string", + "nullable": true + }, + "value": { + "type": "string" + }, + "data": { + "type": "string", + "nullable": true + }, + "operation": { + "description": "Operation type: 0 for CALL, 1 for DELEGATE", + "allOf": [ + { + "$ref": "#/components/schemas/Operation" + } + ] + }, + "safeTxGas": { + "type": "string" + }, + "baseGas": { + "type": "string" + }, + "gasPrice": { + "type": "string" + }, + "gasToken": { + "type": "string", + "nullable": true + }, + "refundReceiver": { + "type": "string", + "nullable": true + }, + "nonce": { + "type": "string", + "description": "The nested Safe's nonce" + }, + "notes": { + "type": "string", + "nullable": true, + "maxLength": 200 + } + }, + "required": [ + "value", + "operation", + "safeTxGas", + "baseGas", + "gasPrice", + "nonce" + ] + }, "ProposeTransactionDto": { "type": "object", "properties": { @@ -15137,6 +17186,16 @@ "origin": { "type": "string", "nullable": true + }, + "nestedTransaction": { + "nullable": true, + "description": "A child transaction for a second Safe, authorised by the parent transaction being an `approveHash` call committing to its hash. Unknown keys are rejected.", + "type": "object", + "allOf": [ + { + "$ref": "#/components/schemas/NestedTransactionDto" + } + ] } }, "required": [ @@ -15435,6 +17494,169 @@ "signature" ] }, + "UpdateDelegateV3Dto": { + "type": "object", + "properties": { + "safe": { + "type": "string", + "nullable": true + }, + "delegate": { + "type": "string" + }, + "delegator": { + "type": "string" + }, + "signature": { + "type": "string" + }, + "label": { + "type": "string" + } + }, + "required": [ + "delegate", + "delegator", + "signature", + "label" + ] + }, + "DeleteDelegateV3Dto": { + "type": "object", + "properties": { + "delegator": { + "type": "string", + "nullable": true + }, + "safe": { + "type": "string", + "nullable": true + }, + "signature": { + "type": "string" + } + }, + "required": [ + "signature" + ] + }, + "NativeTokenMetadata": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "decimals": { + "type": "number" + }, + "logoUri": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "trusted": { + "type": "boolean", + "description": "Whether the Transaction Service lists the token in one of its imported token lists" + }, + "type": { + "type": "string", + "enum": [ + "NATIVE_TOKEN" + ] + } + }, + "required": [ + "address", + "decimals", + "logoUri", + "name", + "symbol", + "trusted", + "type" + ] + }, + "Erc20TokenMetadata": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "decimals": { + "type": "number" + }, + "logoUri": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "trusted": { + "type": "boolean", + "description": "Whether the Transaction Service lists the token in one of its imported token lists" + }, + "type": { + "type": "string", + "enum": [ + "ERC20" + ] + } + }, + "required": [ + "address", + "decimals", + "logoUri", + "name", + "symbol", + "trusted", + "type" + ] + }, + "Erc721TokenMetadata": { + "type": "object", + "properties": { + "address": { + "type": "string" + }, + "decimals": { + "type": "number" + }, + "logoUri": { + "type": "string" + }, + "name": { + "type": "string" + }, + "symbol": { + "type": "string" + }, + "trusted": { + "type": "boolean", + "description": "Whether the Transaction Service lists the token in one of its imported token lists" + }, + "type": { + "type": "string", + "enum": [ + "ERC721" + ] + } + }, + "required": [ + "address", + "decimals", + "logoUri", + "name", + "symbol", + "trusted", + "type" + ] + }, "SafeRegistration": { "type": "object", "properties": { diff --git a/packages/store/src/gateway/AUTO_GENERATED/.schema-hash b/packages/store/src/gateway/AUTO_GENERATED/.schema-hash index 3de9ddc2277..b469e280da8 100644 --- a/packages/store/src/gateway/AUTO_GENERATED/.schema-hash +++ b/packages/store/src/gateway/AUTO_GENERATED/.schema-hash @@ -1 +1 @@ -e9984df7d8acc32efa5370bd62918903c1a9aedda334828d00ef55ff0e922556 +4264aa35dda6529a0e496d1ebb0e6d6357f204d638cb47fad43b6dcc4fe5ffe4 diff --git a/packages/store/src/gateway/AUTO_GENERATED/chains.ts b/packages/store/src/gateway/AUTO_GENERATED/chains.ts index c072860f9cf..a46c104237e 100644 --- a/packages/store/src/gateway/AUTO_GENERATED/chains.ts +++ b/packages/store/src/gateway/AUTO_GENERATED/chains.ts @@ -154,8 +154,11 @@ export type Theme = { export type Relayer = { type: ('GTF' | 'RELAY_FEE' | 'DAILY_LIMIT' | 'NO_FEE_CAMPAIGN') | null safeCreationSponsored: boolean + /** Use gasPaymentOptions instead. */ safeTransactionSponsored: boolean enableTenderlySimulationBeforeRelay: boolean + /** Who may pay for a relayed transaction on this chain. */ + gasPaymentOptions: ('FREE_DAILY_LIMIT' | 'SUBSCRIPTION' | 'PAY_FROM_SAFE' | 'NO_FEE_CAMPAIGN')[] } export type Chain = { chainId: string diff --git a/packages/store/src/gateway/AUTO_GENERATED/delegates.ts b/packages/store/src/gateway/AUTO_GENERATED/delegates.ts index 1cee45c5104..4f7910b2ef1 100644 --- a/packages/store/src/gateway/AUTO_GENERATED/delegates.ts +++ b/packages/store/src/gateway/AUTO_GENERATED/delegates.ts @@ -64,6 +64,43 @@ const injectedRtkApi = api }), invalidatesTags: ['delegates'], }), + delegatesGetDelegatesV3: build.query