warden-protocol / wardenprotocol

Monorepo for the Warden Protocol.
https://wardenprotocol.org
Apache License 2.0
1.1k stars 112 forks source link

[Basic][Warden] Add a type field for signature request #1011

Closed artur-abliazimov closed 1 week ago

artur-abliazimov commented 3 weeks ago
  1. Add a Type (Unspecified=0, BroadcastedByFrontend=1, BroadcastedByScheduler=2 -> think about naming) field for MsgNewSignRequest that represents a transaction that must be relayed automatically without Spaceward.
  2. Add migration to set corresponding type to existing sign requests (=1).
  3. Update precompiles to fetch typed signature requests.
  4. Update wardenjs? ask @Pitasi or @jjheywood to publish the npm package
  5. Ask @alex-nax or @jjheywood to set type on the frontend.
  6. Test if keychain operators works fine.
Svetomech commented 1 week ago

final contract:

Solidity

enum BroadcastType {
    Disabled,
    Automatic
}

struct SignRequest {
    uint64 id;
    address creator;
    uint64 keyId;
    bytes dataForSigning;
    int32 status;
    bytes result;
    bytes encryptionKey;
    Types.Coin[] deductedKeychainFees;
    BroadcastType broadcastType;
}

/// @dev Defines a method to create a new signature request.
/// @param keyId The key id
/// @param input The input
/// @param analyzers The analyzers
/// @param encryptionKey The encryption key
/// @param maxKeychainFees The max keychain fees
/// @param nonce The nonce
/// @param actionTimeoutHeight The block height up until this action can be executed
/// @param expectedApproveExpression The definition of expected approval expression the action is created with
/// @param expectedRejectExpression The definition of expected reject expression the action is created with
/// @param broadcastType The broadcast type
/// @return success If execution was successful
function newSignRequest(
    uint64 keyId,
    bytes calldata input,
    bytes[] calldata analyzers,
    bytes calldata encryptionKey,
    Types.Coin[] calldata maxKeychainFees,
    uint64 nonce,
    uint64 actionTimeoutHeight,
    string calldata expectedApproveExpression,
    string calldata expectedRejectExpression,
    BroadcastType broadcastType
) external returns (bool success);

/// @dev Defines a method to query sign requests.
/// @param pageRequest The pagination details
/// @param keychainId The id of the keychain
/// @param status The sign requests status
/// @param broadcastType The broadcast type
/// @return signRequests An array of `SignRequest` structs containing the retrieved sign requests
/// @return pageResponse  pagination details
function signRequests(
    Types.PageRequest calldata pageRequest,
    uint64 keychainId,
    int32 status,
    BroadcastType broadcastType
) external view returns(SignRequest[] memory signRequests, Types.PageResponse memory pageResponse);

protobuf

// BroadcastType specifies how the transaction should be broadcasted.
enum BroadcastType {
  // The signature should be broadcasted manually by the caller.
  BROADCAST_TYPE_DISABLED = 0;

  // The signature should be automatically broadcasted by an offchain relayer.
  BROADCAST_TYPE_AUTOMATIC = 1;
}

// SignRequest is the request from a user (creator) to a Keychain to sign a
// message (data_for_signing).
//
// Once that the Keychain has received the request, it will either fulfill it
// or reject it. The result of the request will be stored in the result field.
message SignRequest {
  // Unique id of the request.
  uint64 id = 1;

  // Address of the creator of the request.
  string creator = 2;

  // Key ID of the key to be used for signing.
  uint64 key_id = 3;

  // Data to be signed.
  bytes data_for_signing = 4;

  // Status of the request.
  SignRequestStatus status = 5;

  // Result of the request, depending on the status:
  //   If pending, this field is empty.
  //   If approved, this field contains the signed data.
  //   If rejected, this field contains the reason.
  oneof result {
    bytes signed_data = 6 [(amino.oneof_name) = "SignedData"];
    string reject_reason = 7 [(amino.oneof_name) = "RejectReason"];
  }

  bytes encryption_key = 8;

  // Amount of fees deducted during new sign request
  repeated cosmos.base.v1beta1.Coin deducted_keychain_fees = 9 [
    (gogoproto.nullable)     = false,
    (gogoproto.castrepeated) = "github.com/cosmos/cosmos-sdk/types.Coins",
    (amino.dont_omitempty)   = true,
    (amino.encoding)         = "legacy_coins"
  ];

  // Broadcast type of the sign request, indicating how the transaction should be broadcasted.
  BroadcastType broadcast_type = 10;
}

// EventNewSignRequest is emitted on new signature requests
message EventNewSignRequest {
  // id of the signature request
  uint64 id = 1;

  // id of the Key to be used for signing
  uint64 key_id = 2;

  // address of the account that requested the signature
  string creator = 3;

  // broadcast type of the signature request
  BroadcastType broadcast_type = 4;
}

message QuerySignRequestsRequest {
  cosmos.base.query.v1beta1.PageRequest pagination = 1;
  uint64 keychain_id = 2;
  SignRequestStatus status = 3 [ (gogoproto.nullable) = true ];
  BroadcastType broadcast_type = 4 [ (gogoproto.nullable) = true ];
}
Svetomech commented 1 week ago

@jjheywood @alex-nax please publish new NPM package (wardenjs@0.0.12) and set broadcastType on the frontend side