common.token

io.token.proto.common.token /common/src/main/proto/token.proto


syntax = "proto3";
package io.token.proto.common.token;

option java_outer_classname = "TokenProtos";
option csharp_namespace = "Tokenio.Proto.Common.TokenProtos";

import "blob.proto";
import "money.proto";
import "pricing.proto";
import "security.proto";
import "transfer.proto";
import "transferinstructions.proto";
import "alias.proto";
import "extensions/field.proto";
import "extensions/message.proto";

//
// Generic token envelope definition.
//
message Token {
  string id = 1;                                          // Computed as sha(token).
  TokenPayload payload = 2;                               // Token payload, being signed.
  repeated TokenSignature payload_signatures = 3;         // Payload signatures.
  string replaced_by_token_id = 4;                        // ID of the latest token replacing it
  string token_request_id = 5;                            // ID of the token request associated with the token (optional)
}

message TokenRequest {
  string id = 1;                                                                      // request id
  TokenPayload payload = 2;                                                           // token payload
  map<string, string> options = 3 [(io.token.proto.extensions.field.redact) = true]; // generic string map of options
}

message TokenSignature {
  // List of valid actions that one can perform on the Token. We use lowercase string value
  // of the action when computing a signature.
  enum Action {
    INVALID   = 0;
    ENDORSED  = 1;                                        // Endorses token. Both payer and payer bank co-endorse the token.
    CANCELLED = 2;                                        // Revoked by the payer or declined by the redeemer.
  }

  Action action = 1;
  io.token.proto.common.security.Signature signature = 2;
}

// Refers to a Token member by ID or by alias.
message TokenMember {
  string id = 1;                               // member ID
  // TODO(PR-1161): Rename this when we no longer require backwards compatibility with usernames
  string username = 2;
  io.token.proto.common.alias.Alias alias = 3; // alias, such as an email address
}

message TokenPayload {
  string version = 1;                                   // 1.0
  string ref_id = 2;                                    // random string used to de-dupe tokens, set by client.

  TokenMember issuer = 3;                               // Token issuer, bank.
  TokenMember from = 4;                                 // Payer member.
  TokenMember to = 5;                                   // Payee member.

  int64 effective_at_ms = 6;                            // Optional

  // Expiration time. Access tokens ignore this; all access tokens
  // have a 90-day lifespan. For transfer tokens, this is an optional
  // expiration time.
  int64 expires_at_ms = 7;
  int64 endorse_until_ms = 11;                          // Optional, can be endorsed until this time
  string description = 8 [(io.token.proto.extensions.field.redact) = true]; // Optional

  oneof body {
    TransferBody transfer = 9;
    AccessBody access = 10;
  }

  ActingAs acting_as = 12;
  bool receipt_requested = 13;

  // If a token is being created on behalf of another party, this
  // field contains a description of that entity.
  message ActingAs {
    option (io.token.proto.extensions.message.redact) = true;
    string display_name = 1;                            // Name of recipient, to be shown to user
    string ref_id = 2;                                  // Optional reference ID of the recipient. Opaque to Token.
    string logo_url = 3;                                // URL pointing to recipient's logo
    string secondary_name = 4;                          // Optional domain or email of the recipient, to be shown to user along with display_name
  }
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Transfer Token
//

//
// Describes token creation error codes.
//
enum TransferTokenStatus {
  INVALID = 0;
  SUCCESS = 1;
  FAILURE_REJECTED = 2;                          // the request has been rejected
  FAILURE_INSUFFICIENT_FUNDS = 3;                // the request has failed due to insufficient funds
  FAILURE_INVALID_CURRENCY = 4;                  // the request has failed, because currency is invalid/unsupported
  FAILURE_SOURCE_ACCOUNT_NOT_FOUND = 5;          // the request has failed, source account not found
  FAILURE_DESTINATION_ACCOUNT_NOT_FOUND = 6;     // the request has failed, destination account not found
  FAILURE_INVALID_AMOUNT = 10;                   // the request has failed, because the amount is invalid
  FAILURE_INVALID_QUOTE = 11;                    // the request has failed, because the pricing quote is invalid
  FAILURE_EXTERNAL_AUTHORIZATION_REQUIRED = 12;  // the request has failed, because external authorization is needed
  FAILURE_GENERIC = 9;                           // the request has failed due to other reasons
}

message ExternalAuthorizationDetails {
  string url = 1;                // Deprecated. Display content from this URL to user to prompt for permission
  string completion_pattern = 2; // Deprecated. If user navigates to URL matching this pattern, interaction is complete
  string authorization_url = 3;  // Display content from this URL to user to prompt for permission; initiates OAuth payment flow
}

message TransferBody {
  TokenMember redeemer = 1;                                                          // Redeemer member.
  io.token.proto.common.transferinstructions.TransferInstructions instructions = 2;  // Transfer instructions.
  string currency = 4;                                                               // Optional: ISO4217, 3 letter currency code such as "USD" or "EUR".
  string lifetime_amount = 5;                                                        // Optional: Token total lifetime amount. Double.
  string amount = 6;                                                                 // Optional: Single token charge request acceptable range. Double.
  repeated io.token.proto.common.blob.Attachment attachments = 8;                    // Optional: file / data attachments
  io.token.proto.common.pricing.Pricing pricing = 9;                                 // Optional: Transfer fees and fx charges.
}


////////////////////////////////////////////////////////////////////////////////////////////////////
// Access Token
//

message AccessBody {
  repeated Resource resources = 5; // List of resources

  message Resource {
    oneof resource {
      AllAddresses all_addresses = 1;
      AllAccounts all_accounts = 2;
      AllAccountTransactions all_transactions = 3;
      AllAccountBalances all_balances = 4;
      Address address = 5;
      Account account = 6;
      AccountTransactions transactions = 7;
      AccountBalance balance = 8;
      AllAccountsAtBank all_accounts_at_bank = 9;
      AllTransactionsAtBank all_transactions_at_bank = 10;
      AllBalancesAtBank all_balances_at_bank = 11;
    }

    // Provides access to all member addresses
    message AllAddresses {}

    // Provides access to a specific member address
    message Address {
      string address_id = 1; // ID of address
    }

    // Provides access to all member accounts. Enables getAccounts()
    // to get list of accounts (and also getAccount() on any account).
    message AllAccounts {}

    // Provides access to all member accounts at a specific bank.
    message AllAccountsAtBank {
      string bank_id = 1;
    }

    // Provides access to basic info about a specific member account
    // (can call getAccount() on this account).
    message Account {
      string account_id = 1; // ID of account
    }

    // Provides access to member transactions in all accounts
    // Normally used with AllAccounts (to get list of accounts)
    message AllAccountTransactions {}

    // Provides access to member transactions in all accounts at a specific bank.
    // Normally used with AllAccountsAtBank (to get list of accounts)
    message AllTransactionsAtBank {
      string bank_id = 1;
    }

    // Provides access to a specific account transactions
    message AccountTransactions {
      string account_id = 1; // ID of account
    }

    // Provides access to member balance on all accounts
    // Normally used with AllAccounts (to get list of accounts)
    message AllAccountBalances {}

    // Provides access to member balance on all accounts at a specific bank.
    // Normally used with AllAccountsAtBank (to get list of accounts)
    message AllBalancesAtBank {
      string bank_id = 1;
    }

    // Provides access to a specific account's balance
    message AccountBalance {
      string account_id = 1; // ID of account
    }
  }
}

//
// Token operation status
//
message TokenOperationResult {
  Token token = 1;   // Token, perhaps with new signatures
  Status status = 2; // Success/failure status

  enum Status {
    INVALID = 0;
    SUCCESS = 1;                // Operation succeeded.
    // Token needs more signatures.
    // If that's surprising: Perhaps used LOW or STANDARD key but needs PRIVILEGED?
    MORE_SIGNATURES_NEEDED = 2;
  }
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Request signature
//

message TokenRequestStatePayload {
  string token_id = 1;
  string state = 2;
}