syntax = "proto3";

import "proto/loom.proto";

enum TransferGatewayTokenKind {
    ETH = 0;
    ERC20 = 1;
    ERC721 = 2;
    ERC721X = 3;
    LOOMCOIN = 4;
    TRX = 5;
    TRC20 = 6;
    BEP2_LOOM = 7;
    BEP2 = 8;
}

enum TransferGatewayTxStatus {
    PENDING = 0;
    PROCESSED = 1;
    CONFIRMED = 2;
    REJECTED = 3;
}

message TransferGatewayState {
    Address owner = 1;
    // Last Mainnet block processed by the Transfer Gateway contract
    uint64 last_mainnet_block_num = 2;
    // ID that should be used for the next pending contract mapping
    uint64 next_contract_mapping_id = 3;
    // Token owners that have initiated (but have not as yet completed) a withdrawal to Mainnet.
    repeated Address token_withdrawers = 4;
    // Binance Dex transfer fee. This will be used for binance gateway
    BigUInt transfer_fee = 5;
    // Mainnet Gateway address
    Address mainnet_gateway_address = 6;
    // Mainnet Hot Wallet address
    Address mainnet_hot_wallet_address = 7;
    // Max total ETH or LOOM withdrawal amount the gateway will allow in a 24 hour withdrawal period
    BigUInt max_total_daily_withdrawal_amount = 8;
    // Max per-account ETH or LOOM withdrawal amount the gateway will allow in a 24 hour withdrawal period
    BigUInt max_per_account_daily_withdrawal_amount = 9;
    // Last time the 24 hour withdrawal period was reset
    int64 last_withdrawal_limit_reset_time = 10;
    // Total amount of ETH or LOOM (depending on the Gateway) withdrawn through this gateway within
    // the last 24 hour withdrawal period (which started at last_withdrawal_limit_reset_time)
    BigUInt total_withdrawal_amount = 11;
}

message TransferGatewayStateRequest {
}

message TransferGatewayStateResponse {
    TransferGatewayState state = 1;
}

message TransferGatewayWithdrawalReceipt {
    // Mainnet address of token owner
    Address token_owner = 1;
    // Mainnet address of token contract
    Address token_contract = 2;
    TransferGatewayTokenKind token_kind = 3;
    // ERC721/X token ID
    BigUInt token_id = 4;
    // ERC721X/ERC20/ETH amount
    BigUInt token_amount = 5;
    uint64 withdrawal_nonce = 6;
    // Signature generated by the Oracle that confirmed the withdrawal
    bytes oracle_signature = 7;
    // Withdrawal tx hash on the foreign chain (currently only used by Binance Gateway)
    bytes tx_hash = 9;
    // Withdrawal tx status on the foreign chain (currently only used by Binance Gateway)
    TransferGatewayTxStatus tx_status = 10;
}

// Events emitted by the contract

message TransferGatewayContractMappingConfirmed {
    // Address of a contract on a foreign blockchain
    Address foreign_contract = 1;
    // Address of corresponding contract on the local blockchain
    Address local_contract = 2;
}

// Emitted when a withdrawal to the Mainnet Gateway has been signed.
// This event contains all the required data to complete a toke withdrawal via the Mainnet Gateway.
message TransferGatewayTokenWithdrawalSigned {
    // Mainnet address of token owner
    Address token_owner = 1;
    // Mainnet address of token contract, blank if ETH
    Address token_contract = 2;
    TransferGatewayTokenKind token_kind = 3;
    // ERC721/X token ID
    BigUInt token_id = 4;
    // ERC721X/ERC20/ETH amount
    BigUInt token_amount = 5;
    // Oracle signature
    bytes sig = 6;
}

// Request & Response

// Contract Mapping
message TransferGatewayAddContractMappingRequest {
    // Address on foreign blockchain
    Address foreign_contract = 1;
    // Corresponding address on local blockchain
    Address local_contract = 2;
    // Signature of the creator of the foreign contract
    bytes foreign_contract_creator_sig = 3;
    // Hash of the transaction which created the foreign contract
    bytes foreign_contract_tx_hash = 4;
}

// Recovery

// Transfer unclaimed tokens to the sender, or to the specified depositors
message TransferGatewayReclaimDepositorTokensRequest {
    // Foreign address of depositors
    repeated Address depositors = 1;
}

// Transfer any unclaimed tokens originating from a specific contract to their depositors
message TransferGatewayReclaimContractTokensRequest {
    // Foreign address of token contract
    Address token_contract = 1;
}

// Withdrawal Management

message TransferGatewayWithdrawTokenRequest {
    // ERC721/X/ERC20 contract DAppChain address
    Address token_contract = 1;
    TransferGatewayTokenKind token_kind = 2;
    // ERC721/X token ID
    BigUInt token_id = 3;
    // ERC721X/ERC20 amount
    BigUInt token_amount = 4;
    // Ethereum address of the account that should receive the token.
    // If this field is omitted the Gateway will attempt to obtain the recipient address from a
    // previously created mapping between the sender's DAppChain address and their Ethereum address,
    // if no such mapping exists the request will error out.
    Address recipient = 5;
}

message TransferGatewayWithdrawETHRequest {
    // Amount of ETH to withdraw
    BigUInt amount = 1;
    // Address of Mainnet Gateway contract -- TODO: This is redundant and
    // should be removed in a subsequent PR.
    Address mainnet_gateway = 2;
    // Ethereum address of the account that should receive the ETH.
    // If this field is omitted the Gateway will attempt to obtain the recipient address from a
    // previously created mapping between the sender's DAppChain address and their Ethereum address,
    // if no such mapping exists the request will error out.
    Address recipient = 3;
}


message TransferGatewayWithdrawLoomCoinRequest {
    // Amount of Loomcoin to withdraw
    BigUInt amount = 1;
    // Address of Mainnet Loomcoin contract
    Address token_contract = 2;
    // Ethereum address of the account that should receive the Loomcoin.
    // If this field is omitted the Gateway will attempt to obtain the recipient address from a
    // previously created mapping between the sender's DAppChain address and their Ethereum address,
    // if no such mapping exists the request will error out.
    Address recipient = 3;
}

message TransferGatewayWithdrawalReceiptRequest {
    Address owner = 1;
}

message TransferGatewayWithdrawalReceiptResponse {
    TransferGatewayWithdrawalReceipt receipt = 1;
}

message TransferGatewayConfirmWithdrawalReceiptRequest {
    // DAppChain address of the entity attempting to make the withdrawal
    Address token_owner = 1;
    // 66-byte hash of the withdrawal hash
    bytes oracle_signature = 2;
    // 32-byte hash of the withdrawal details
    bytes withdrawal_hash = 3; // TODO: figure out if there's any point passing this around
}

message TransferGatewayTokenAmount {
    BigUInt token_id = 1;
    BigUInt token_amount = 2;
}

// Stores all unclaimed tokens of a depositor for a single contract.
message TransferGatewayUnclaimedToken {
    // Foreign address of token contract
    Address token_contract = 1;
    TransferGatewayTokenKind token_kind = 2;
    // For ERC721 this is a list of token IDs (amount is omitted because it should always be 1).
    // For ERC721X this is a list of token IDs with the corresponding amount of each token.
    // For ERC20/ETH this list will contain a single value containing the total unclaimed ERC20/ETH amount.
    repeated TransferGatewayTokenAmount amounts = 3;
}

message TransferGatewayGetUnclaimedTokensRequest {
    Address owner = 1;
}

message TransferGatewayGetUnclaimedTokensResponse {
    repeated TransferGatewayUnclaimedToken unclaimed_tokens = 1;
}

message TransferGatewayResubmitWithdrawalRequest {
}

// Fetches a specific contract mapping.
message TransferGatewayGetContractMappingRequest {
    Address from = 1;
}

message TransferGatewayGetContractMappingResponse {
    Address mapped_address = 1;
    bool is_pending = 2;
    bool found = 3;
}

message TransferGatewayListContractMappingRequest {
}

message TransferGatewayListContractMappingResponse {
    repeated TransferGatewayContractAddressMapping confimed_mappings = 1;
    repeated TransferGatewayPendingContractMapping pending_mappings = 2;
}

message TransferGatewayContractAddressMapping {
    // Address on a blockchain
    Address from = 1;
    // Corresponding address on another blockchain
    Address to = 2;
}

message TransferGatewayPendingContractMapping {
    uint64 ID = 1;
    // Address on foreign blockchain
    Address foreign_contract = 2;
    // Corresponding address on local blockchain
    Address local_contract = 3;
    // Foreign address of the creator of the foreign contract
    Address foreign_contract_creator = 4;
    // Hash of the transaction which created the foreign contract
    bytes foreign_contract_tx_hash = 5;
}

message TransferGatewayGetLocalAccountInfoRequest {
    // Owner address
    Address owner = 1;
}

message TransferGatewayGetLocalAccountInfoResponse {
    // Local owner of the account
    Address owner = 1;
    // Pending withdrawal receipt (if any)
    TransferGatewayWithdrawalReceipt withdrawal_receipt = 2;
    // Total amount of ETH or LOOM (depending on the Gateway) withdrawn by this account within the
    // last 24 hour withdrawal period (which started at last_withdrawal_limit_reset_time)
    BigUInt total_withdrawal_amount = 3;
    // Last time the 24 hour withdrawal period was reset for this account
    int64 last_withdrawal_limit_reset_time = 4;
}
