xand-api-proto 49.0.0

Protobuf definitions for the Xand API
Documentation
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
syntax = "proto3";
package xand_api;

import "google/api/annotations.proto";

service XandApi {
    // For submitting transactions to the network. See the `UserTransaction` type for details
    // about which transactions may be submitted.
    rpc SubmitTransaction (UserTransaction) returns (stream TransactionUpdate) {
        option (google.api.http) = {
            post: "/v1/transactions"
            body: "*"
        };
    }

    // For proposing administrative transactions to the network. See the `AdministrativeTransaction`
    // type for details about which transactions may be submitted.
    rpc ProposeAction (SubmitProposal) returns (stream TransactionUpdate) {
        option (google.api.http) = {
            post: "/v1/proposals"
            body: "*"
        };
    }

    // For voting on outstanding proposals. See the `VotingTransactions` type for details about
    // which transactions may be submitted.
    rpc VoteOnProposal (VotingTransaction) returns (stream TransactionUpdate) {
        option (google.api.http) = {
            post: "/v1/voting"
            body: "*"
        };
    }

    // For querying data on specific Proposal by id
    rpc GetProposal (GetProposalReq) returns (Proposal) {
        option (google.api.http) = {
            get: "/v1/proposals/{id}"
        };
    }

    // For querying a list of all non-expired Proposals
    rpc GetAllProposals (GetAllProposalsReq) returns (Proposals) {
        option (google.api.http) = {
            get: "/v1/proposals"
        };
    }

    rpc GetTrustee (GetTrusteeReq) returns (TrusteeData) {
        option (google.api.http) = {
            get: "/v1/trustee"
        };
    }

    rpc GetLimitedAgent (GetLimitedAgentReq) returns (LimitedAgentData) {
        option (google.api.http) = {
            get: "/v1/trustee"
        };
    }

    // To request the details (including its status) of a transaction by ID
    rpc GetTransactionDetails (TransactionDetailsRequest) returns (FetchedTransaction) {
        // NOTE: This must, for now, delegate to petri. Later, it should delegate to the
        //   service parity has said they're working on that maintains txn history.
        option (google.api.http) = {
            get: "/v1/transactions/{id}"
        };
    }

    // For requesting historical transaction data. Only returns transactions which have been
    // finalized on the chain.
    //
    // **TODO** -- A request with no addresses results in every transaction in the cache being
    //   returned, without meaningful order. We need to make changes to the backend.
    rpc GetTransactionHistory (TransactionHistoryRequest) returns (TransactionHistory) {
        option (google.api.http) = {
            get: "/v1/transactions"
        };
    }

    // For requesting the balance an address has
    rpc GetAddressBalance (AddressBalanceRequest) returns (AddressBalance) {
        option (google.api.http) = {
            get: "/v1/addresses/{address}/balance"
        };
    }

    // For requesting the total amount of claims on the network
    rpc GetTotalIssuance (TotalIssuanceRequest) returns (TotalIssuanceResponse) {
        option (google.api.http) = {
            get: "/v1/total-issuance/balance"
        };
    }

    // For requesting transactions that affect a given address
    rpc GetAddressTransactions (AddressTransactionHistoryRequest) returns (TransactionHistory) {
        option (google.api.http) = {
            get: "/v1/addresses/{address}/transactions"
        };
    }

    // For enumerating the currently outstanding create requests
    rpc GetPendingCreateRequests (PendingCreateRequestsPagination) returns (PendingCreateRequests) {
        option (google.api.http) = {
            get: "/v1/pending-create-requests"
        };
    }

    // For enumerating the currently outstanding redeem requests
    rpc GetPendingRedeemRequests (PendingRedeemRequestsPagination) returns (PendingRedeemRequests) {
        option (google.api.http) = {
            get: "/v1/pending-redeem-requests"
        };
    }

    // For retrieving the list of allowlisted CIDR blocks.
    rpc GetAllowlist (AllowlistRequest) returns (Allowlist) {
        option (google.api.http) = {
            get: "/v1/allowlist"
        };
    }

    // For enumerating the current members
    rpc GetMembers (MembersRequest) returns (Members) {
        option (google.api.http) = {
            get: "/v1/members"
        };
    }

    // For enumerating the current authority keys (validators)
    rpc GetAuthorityKeys (AuthorityKeysRequest) returns (AuthorityKeys) {
        option (google.api.http) = {
            get: "/v1/authority-keys"
        };
    }

    // For retrieving the public encryption key of an account on the network
    rpc GetEncryptionKey (EncryptionKeyRequest) returns (EncryptionKey) {
        option (google.api.http) = {
            get: "/v1/encryption-key"
        };
    }

    // Returns the most current block and timestamp in a single blockstamp message with a staleness indicator
    rpc GetCurrentBlock (GetCurrentBlockReq) returns (Blockstamp) {
        option (google.api.http) = {
            get: "/v1/now"
        };
    }

    rpc GetValidatorEmissionRate (GetValidatorEmissionRateReq) returns (ValidatorEmissionRate) {
        option (google.api.http) = {
            get: "/v1/validators/emissions/rate"
        };
    }

    rpc GetValidatorEmissionProgress (GetValidatorEmissionProgressReq) returns (ValidatorEmissionProgress) {
        option (google.api.http) = {
            get: "/v1/validators/emissions/{address}"
        };
    }

    rpc GetPendingCreateRequestExpireTime (GetPendingCreateRequestExpireTimeReq) returns (PendingCreateRequestExpireTime) {
        option (google.api.http) = {
            get: "/v1/trustee/pending-create-request-expire-time"
        };
    }

    rpc CheckHealth(HealthCheckRequest) returns (HealthCheckResponse);
}


enum HealthStatus {
    UNHEALTHY = 0;
    HEALTHY = 1;
    SYNCING = 2;
}
message HealthCheckRequest {}
message HealthCheckResponse {
    HealthStatus status = 1;
    uint64 current_block = 2;
    uint64 elapsed_blocks_since_startup = 3;
    int64 elapsed_time_since_startup_millis = 4;
    uint64 best_known_block = 5;
}

message GetCurrentBlockReq {}
message Blockstamp {
    uint64 block_number = 1;
    Timestamp timestamp = 2;
    bool is_stale = 3;
}

message TransactionDetailsRequest {
    // The hashed transaction identifier
    string id = 1;
}

message FetchedTransaction {
    // The hashed transaction identifier
    string id = 1;
    AnyTransaction transaction = 2;
    TransactionStatus status = 3;
    int64 unix_time_millis = 4;
}

message Proposals {
    // List of non-expired Proposals
    repeated Proposal proposals = 1;
}

message Proposal {
    // Unique Proposal Id
    uint32 id = 1;
    // Map of voters to their votes, true is yes, false is no
    map<string, bool> votes = 2;
    // Address of party that created Proposal
    string proposer = 3;
    // Blockchain Block on which Proposal will expire and be removed
    uint32 expiration_block_id = 4;
    // The action that will be executed if this Proposal is accepted
    AdministrativeTransaction proposed_action = 5;
    // Possible states the Proposal can be in
    enum ProposalStatus {
        // Open for votes
        PROPOSED = 0;
        // Accepted by voters and executed
        ACCEPTED = 1;
        // Rejected by voters
        REJECTED = 2;
        // Accepted by voters, but could not be executed
        INVALID = 3;
    }
    // This proposal's current state
    ProposalStatus status = 6;
}

message TransactionHistoryRequest {
    // The pagination technique follows Google's advice for grpc:
    // https://cloud.google.com/apis/design/design_patterns#list_pagination

    // SS58 public key address(es) whose history we are concerned with. Any transactions affecting
    // these addresses will appear in the history, not just transactions an address has issued.
    // Leaving this field empty, or as an empty list, results in *all* transactions being returned.
    repeated string addresses = 1;
    // Clients use this field to specify the maximum number of results to be returned by the server.
    // The server may further constrain the maximum number of results returned in a single page.
    // If the page_size is 0, the server will decide the number of results to be returned.
    uint32 page_size = 2;
    // Which page number to fetch.
    //
    // This violates best practices around pagination. We should be using a cursor instead,
    // but there's not really a point until we're using an actual database.
    uint32 page_number = 3;
    // Types of transactions to return. If empty, transactions of all types are returned.
    repeated TransactionType transaction_types = 4;
    // [Optional] Only transactions after the specified time are returned. Unbounded if none.
    Timestamp start_time = 5;
    // [Optional] Only transactions before the specified time are returned. Unbounded if none.
    Timestamp end_time = 6;
}

message TransactionHistory {
    // The transactions matching the history request
    repeated FetchedTransaction transactions = 1;

    // TODO: Restore when we have a DB
    // The pagination token to retrieve the next page of results. If the value is "", it means no
    // further results for the request.
    //    string next_page_token = 2;

    // The total number of transactions matching the request
    uint32 total = 3;
}

message TotalIssuanceRequest {
}

message TotalIssuanceResponse {
    uint64 balance = 1;

    Blockstamp blockstamp = 2;
}

message AddressBalanceRequest {
    // The ss58 address of the account whose balance we are requesting
    string address = 1;
}

message AddressBalance {
    // [Optional] The balance of claims held by an address, if the requester can read it.
    MaybeBalance balance = 1;
}

message MaybeBalance {
    // The balance of claims held by an address, denominated in USD cents
    uint64 amount = 1;
}

message Issuer {
    string issuer = 1;
}

message AddressTransactionHistoryRequest {
    // This must be separate from `TransactionHistoryRequest` so that we can enforce we are only
    // talking about *one* address.

    // The SS58 public key address whose history we are concerned with. Any transactions affecting
    // this address will appear in the history, not just transactions which the address has issued.
    string address = 1;
    // Clients use this field to specify the maximum number of results to be returned by the server.
    // The server may further constrain the maximum number of results returned in a single page.
    // If the page_size is 0, the server will decide the number of results to be returned.
    uint32 page_size = 2;
    // Which page number to fetch.
    //
    // This violates best practices around pagination. We should be using a cursor instead,
    // but there's not really a point until we're using an actual database.
    uint32 page_number = 3;
}

message PendingCreateRequestsPagination {
    // Clients use this field to specify the maximum number of results to be returned by the server.
    // The server may further constrain the maximum number of results returned in a single page.
    // If the page_size is 0, the server will decide the number of results to be returned.
    uint32 page_size = 2;
    // Which page number to fetch.
    //
    // This violates best practices around pagination. We should be using a cursor instead,
    // but there's not really a point until we're using an actual database.
    uint32 page_number = 3;
}

message PendingCreateRequests {
    repeated PendingCreateRequest pending_create_requests = 1;

    // TODO: Restore when we have a DB
    // The pagination token to retrieve the next page of results. If the value is "", it means no
    // further results for the request.
    //    string next_page_token = 2;

    // The total number of pending create requests matching the request
    uint32 total = 3;
}

// A create request that has been submitted and may not have been confirmed or cancelled yet.
message Create {
    CreateRequest request = 1;
    CreateRequestCompletion completing_transaction = 2;
}

message PendingCreateRequest {
    // The ss58 address of the account who requested the create request
    Issuer issuer = 1;
    // The correlation id identifying the create request (transaction ID of the create request)
    string correlation_id = 2;
    // The underlying request
    CreateRequest request = 3;
}

message PendingRedeemRequestsPagination {
    // Clients use this field to specify the maximum number of results to be returned by the server.
    // The server may further constrain the maximum number of results returned in a single page.
    // If the page_size is 0, the server will decide the number of results to be returned.
    uint32 page_size = 2;
    // Which page number to fetch.
    //
    // This violates best practices around pagination. We should be using a cursor instead,
    // but there's not really a point until we're using an actual database.
    uint32 page_number = 3;
}

message PendingRedeemRequests {
    repeated PendingRedeemRequest pending_redeem_requests = 1;

    // TODO: Restore when we have a DB
    // The pagination token to retrieve the next page of results. If the value is "", it means no
    // further results for the request.
    //    string next_page_token = 2;

    // The total number of pending create requests matching the request
    uint32 total = 3;
}

message AllowlistRequest {}

message Allowlist {
    repeated AllowlistEntry entries = 1;
}

// A redeem request that has been submitted and may not have been fulfilled or cancelled yet.
message Redeem {
    RedeemRequest request = 1;
    RedeemRequestCompletion completing_transaction = 2;
}

message PendingRedeemRequest {
    // The ss58 address of the account who requested the claim redeem
    Issuer issuer = 1;
    // The correlation id identifying the pending redeem request (transaction ID of the redeem)
    string correlation_id = 2;
    // The underlying request
    RedeemRequest request = 3;
}

// Transactions which any user may issue. These represent the most common
// transactions on the network and require no special privileges.
message UserTransaction {
    // The ss58 address of the account that issued or is issuing this transaction
    string issuer = 1;
    // The transaction being issued
    oneof operation {
        // Send claims from one party to another
        Send send = 10;
        // A request to convert fiat into claims
        CreateRequest create_request = 11;
        // A request to convert claims into fiat
        RedeemRequest redeem_request = 12;
        // Issued when fulfilling a `CreateRequest`
        CashConfirmation cash_confirmation = 13;
        // Issued when a `RedeemRequest` has been fulfilled
        RedeemFulfillment redeem_fulfillment = 14;
        // Issued to cancel pending create requests
        CreateCancellation create_cancellation = 15;
        // Issued to add a CIDR block to their allowlist
        AllowlistCidrBlock allowlist_cidr_block = 17;
        // Issued to remove a CIDR block from their allowlist
        RemoveAllowlistCidrBlock remove_cidr_block = 18;
        // Issued to cancel pending redeem requests
        RedeemCancellation redeem_cancellation = 19;
        // Issued to register session keys
        RegisterSessionKeys register_session_keys = 20;
        // Issued to set how long pending create requests are valid before they expire
        SetPendingCreateRequestExpire set_pending_create_request_expire = 21;
        // Initiate voluntary withdrawal
        WithdrawFromNetwork withdraw_from_network = 22;
    }
}

message SubmitProposal {
    // The ss58 address of the account that issued or is issuing this transaction
    string issuer = 1;
    // One of the Administrative Transactions
    AdministrativeTransaction proposed_action = 2;
}

// Transactions which can only be issued by root (network)
message AdministrativeTransaction {
    // The transaction being issued
    oneof operation {
        // Issued to register members
        RegisterAccountAsMember register_account_as_member = 10;
        // Issued to set the identity of the trust
        SetTrust set_trust = 11;
        // Issued to add a new keypair for a validator which may participate in consensus
        AddAuthorityKey add_authority_key = 12;
        // Issued to remove a keypair for an existing validator
        RemoveAuthorityKey remove_authority_key = 13;
        // Issued to add a CIDR block to the allowlist
        RootAllowlistCidrBlock root_allowlist_cidr_block = 14;
        // Issued to remove a CIDR block from the allowlist
        RootRemoveAllowlistCidrBlock root_remove_allowlist_cidr_block = 15;
        // Update runtime code
        RuntimeUpgrade runtime_upgrade = 16;
        // Mark Member for removal
        RemoveMember remove_member = 17;
        // Set (or unset) Limited Agent
        SetLimitedAgent set_limited_agent = 20;
        // Set the emission rate for validator payments
        SetValidatorEmissionRate set_validator_emission_rate = 21;
    }
}

message VotingTransaction {
    string issuer = 1;
    VoteProposal vote_proposal = 10;
}

// All submitted transactions on the network are represented here
message AnyTransaction {
    // The ss58 address of the account that issued or is issuing this transaction
    string issuer = 1;
    // The transaction being issued
    oneof operation {
        // Send claims from one party to another
        Send send = 10;
        // A request to convert fiat into claims
        Create create_request = 11;
        // A request to convert claims into fiat
        Redeem redeem_request = 12;
        // Issued by the trust when fulfilling a `CreateRequest`
        CashConfirmation cash_confirmation = 13;
        // Issued by the trust when a `RedeemRequest` has been fulfilled
        RedeemFulfillment redeem_fulfillment = 14;
        // Issued by the trust to cancel pending create requests
        CreateCancellation create_cancellation = 17;
        // Issued to add a CIDR block to the allowlist
        AllowlistCidrBlock allowlist_cidr_block = 18;
        // Issued to remove a CIDR block from the allowlist
        RemoveAllowlistCidrBlock remove_cidr_block = 19;
        // Issued by root to register members
        RegisterAccountAsMember register_account_as_member = 20;
        // Issued by root to set the identity of the trust
        SetTrust set_trust = 21;
        // Issued by root to add a new keypair for a validator which may participate in consensus
        AddAuthorityKey add_authority_key = 22;
        // Issued by root to remove a keypair for an existing validator
        RemoveAuthorityKey remove_authority_key = 23;
        // Issued by root to add a CIDR block to the allowlist
        RootAllowlistCidrBlock root_allowlist_cidr_block = 24;
        // Issued by root to remove a CIDR block from the allowlist
        RootRemoveAllowlistCidrBlock root_remove_allowlist_cidr_block = 25;
        // Issued by trust to set how long pending create requests are valid before they expire
        SetPendingCreateRequestExpire set_pending_create_request_expire = 26;
        // Issued by member or validator, issuer not included
        SubmitProposal submit_proposal = 27;
        // Issued by member or validator as a vote on specific proposal
        VoteProposal vote_proposal = 28;
        // Issued to cancel pending redeem requests
        RedeemCancellation redeem_cancellation = 31;
        // Update runtime code
        RuntimeUpgrade runtime_upgrade = 32;
        // Mark Member for removal
        RemoveMember remove_member = 33;
        // Set member encryption public key
        SetMemberEncryptionKey set_member_encryption_key = 34;
        // Set trust encryption public key
        SetTrustEncryptionKey set_trust_encryption_key = 35;
        // Register session keys
        RegisterSessionKeys register_session_keys = 38;
        // Set (or unset) Limited Agent
        SetLimitedAgent set_limited_agent = 39;
        // Set the emission rate for validator payments
        SetValidatorEmissionRate set_validator_emission_rate = 40;
        // Immediately exit Member
        ExitMember exit_member = 41;
        // Initiate voluntary withdrawal
        WithdrawFromNetwork withdraw_from_network = 42;
    }
}

// A request to send claims on-chain from one party to another
message Send {
    // The SS58 encoded address of the party to send claims to
    string to = 1;
    // The number of claims, in minor units (cents for USD) to send
    uint64 amount = 2;
}

// Unencrypted bank account details
message UnencryptedBankAccount {
    string routing_number = 1;
    string account_number = 2;
}

// Encrypted bank account details
message EncryptedBankAccount {
    EncryptionError encryption_error = 1;
}

// Encryption errors
message EncryptionError {
    oneof error {
        // Missing key error
        KeyNotFound key_not_found = 10;
        // Cyphertext could not be decrypted because it was malformed
        MessageMalformed message_malformed = 11;
    }
}

message KeyNotFound {}
message MessageMalformed {}
// Bank account details
message BankAccount {
    oneof account {
        // Unencrypted bank account details
        UnencryptedBankAccount unencrypted_bank_account = 10;
        // Encrypted bank account details
        EncryptedBankAccount encrypted_bank_account = 11;
    }
}

// Define withdrawal
message WithdrawFromNetwork {}

// The reason / identifier a create request was completed
message CreateRequestCompletion {
    oneof id {
        // A transaction ID
        string confirmation = 10;
        // A transaction ID
        string cancellation = 11;
        // A transaction ID
        string expiration = 12;
    }
}

// The reason / identifier a redeem request was completed
message RedeemRequestCompletion {
    oneof id {
        // A transaction ID
        string confirmation = 10;
        // A transaction ID
        string cancellation = 11;
    }
}

// A request to confirm cash as claims on the network
message CreateRequest {
    // The amount of fiat money, in minor units (cents for USD) to convert into on-chain claims
    uint64 amount = 1;
    // The identifier that the Trust will use to decide where fiat funds should be transferred.
    BankAccount bank_account = 2;
    // Uniquely identifies the request
    string correlation_id = 3;
}

// Issued by the trust when fulfilling a `CreateRequest`
message CashConfirmation {
    // Uniquely identifies the create request being fulfilled
    string correlation_id = 1;
}

// A request to redeem on-chain funds
message RedeemRequest {
    // The amount of claims, in minor units (cents for USD) to redeem into fiat funds
    uint64 amount = 1;
    // The identifier that the Trust will use to decide where fiat funds should be transferred.
    BankAccount bank_account = 2;
    // Uniquely identifies the request
    string correlation_id = 3;
}

// Issued by the trust when a `RedeemRequest` has been fulfilled
message RedeemFulfillment {
    // Uniquely identifies the redeem request being fulfilled
    string correlation_id = 1;
}

// Issued by the trust to cancel pending create requests
message CreateCancellation {
    // Uniquely identifies the create request being cancelled
    string correlation_id = 1;
    // The reason the create request was cancelled
    string reason = 2;
}

// Issued by the trust to cancel pending redeem requests
message RedeemCancellation {
    // Uniquely identifies the redeem request being cancelled
    string correlation_id = 1;
    // The reason the redeem request was cancelled
    string reason = 2;
}

// Issued by a validator to register their session keys
message RegisterSessionKeys {
    // SS58 Session public key for block production
    string block_production_pubkey = 1;
    // SS58 Session public key for block finalization
    string block_finalization_pubkey = 2;
}

// Issued to add a CIDR block to the allowlist
message AllowlistCidrBlock {
    // The cidr block to allowlist. In X.X.X.X/X format
    string cidr_block = 1;
}

// Issued to remove a CIDR block from the allowlist
message RemoveAllowlistCidrBlock {
    // The cidr block to remove from the allowlist. In X.X.X.X/X format
    string cidr_block = 1;
}

message SetPendingCreateRequestExpire {
    // Expiration time in milliseconds
    uint64 expire_in_milliseconds = 1;
}

message GetValidatorEmissionRateReq {}

message ValidatorEmissionRate {
    uint64 minor_units_per_emission = 1;
    uint32 block_quota = 2;
}

message GetValidatorEmissionProgressReq {
    string address = 1;
}

message ValidatorEmissionProgress {
    ValidatorEmissionRate effective_emission_rate = 1;
    uint32 blocks_completed_progress = 2;
}

message GetPendingCreateRequestExpireTimeReq {}

message PendingCreateRequestExpireTime {
    uint64 expire_in_milliseconds = 1;
}

// Transactions that require root privileges / will become vote-on-able ============================

// Issued by root to register members
message RegisterAccountAsMember {
    // The SS58 public key address to register as a member
    string address = 1;

    // The X25519 public key for encryption. Must be 32 bytes.
    bytes encryption_key = 2;
}

// Issued by root to mark Members for removal
message RemoveMember {
    // The SS58 public key address to register as a member
    string address = 1;
}

// Issued by root to immediately exit Members
message ExitMember {
    // The SS58 public key address to register as a member
    string address = 1;
}

// Issued by root to set the identity of the trust
message SetTrust {
    // The SS58 public key address of the new trust keypair
    string address = 1;

    // The X25519 public key for encryption. Must be 32 bytes.
    bytes encryption_key = 2;
}

// A dummy message containing a string. Due to protobuf's optional-messages-by-default
// behavior, this message will be optional in a containing message.
message OptionalAddress {
    string address_str = 1;
}

// Issued by root to set the identity of the Limited Agent
message SetLimitedAgent {
    // The SS58 public key address of the new Limited Agent. Optional/can be omitted to remove the
    // LA entirely.
    OptionalAddress address = 1;
}

// Issued by root to select the amount and frequency of payments to Validators
message SetValidatorEmissionRate {
    // Amount paid, in minor units, per "emission period" (number of blocks defined below)
    uint64 minor_units_per_emission = 1;

    /// Interval (number of blocks produced) between each payout
    uint32 block_quota = 2;
}

// Issued by members to set the pubkey that should be used for encrypting data to be shared with
// them
message SetMemberEncryptionKey {
    // The new X25519 public key to register for encryption. Must be 32 bytes.
    bytes encryption_key = 2;
}

// Issued by trust to set the pubkey that should be used for encrypting data only to be shared with
// the trust.
message SetTrustEncryptionKey {
    // The new X25519 public key to register for encryption. Must be 32 bytes.
    bytes encryption_key = 1;
}

// Issued by root to add a new keypair for a validator which may participate in consensus
message AddAuthorityKey {
    // The SS58 public key address of the new validator
    string address = 1;
}

// Issued by root to remove a keypair for an existing validator
message RemoveAuthorityKey {
    // The SS58 public key address of the existing validator
    string address = 1;
}

// Issued by root to add a CIDR block to the allowlist
message RootAllowlistCidrBlock {
    // The cidr block to allowlist. In X.X.X.X/X format
    string cidr_block = 1;
    // The SS58 public key address to whose allowlist we should add the block
    string address = 2;
}

// Issued by root to remove a CIDR block from the allowlist
message RootRemoveAllowlistCidrBlock {
    // The cidr block to remove from the allowlist. In X.X.X.X/X format
    string cidr_block = 1;
    // The SS58 public key address from whose allowlist we should remove the block
    string address = 2;
}

// Issued by network voter to add vote for Proposal with specified id
message VoteProposal {
    // Proposal id
    uint32 id = 1;
    // Vote, true for yes, false for no
    bool vote = 2;
}

// Query for the state of a specific Proposal
message GetProposalReq {
    uint32 id = 1;
}

// Query for the state of all Proposals
message GetAllProposalsReq {}

// Query the information on the Trustee Node
message GetTrusteeReq {}

// Trustee Node information
message TrusteeData {
    string address = 1;
}

// Query the information on the Limited Agent
message GetLimitedAgentReq {}

// Limited Agent information
message LimitedAgentData {
    // Address of the limited agent.  Unset / None if there is no Limited Agent.
    OptionalAddress address = 1;
}

message RuntimeUpgrade {
    bytes code = 1;
    bytes xand_hash = 2;
    uint32 wait_blocks = 3;
}

// =================================================================================================

message TransactionUpdate {
    // The transaction's identifier (transaction hash)
    string id = 1;
    // The current status of the transaction
    TransactionStatus status = 2;
}

// Represents the status of an individual transaction
message TransactionStatus {
    oneof status {
        // Transaction has been received by the API
        TransactionReceived received = 10;
        // Transaction has been accepted by the validator into the transaction pool
        TransactionAccepted accepted = 11;
        // Transaction has been broadcast to other validators
        TransactionBroadcast broadcast = 12;
        // Transaction was marked as invalid
        TransactionInvalid invalid = 13;
        // The transaction was dropped because load is too high
        TransactionDropped dropped = 14;
        // The transaction was finalized
        TransactionCommitted committed = 15;
        // The transaction was finalized
        TransactionFinalized finalized = 16;
    }
}

message TransactionReceived {
}
message TransactionAccepted {
}
message TransactionBroadcast {
    // Validator identifiers transaction was broadcast to
    repeated string validator_ids = 1;
}
message TransactionInvalid {
    // Reason the transaction was deemed invalid
    string reason = 1;
}
message TransactionDropped {
    // Reason the transaction was dropped
    string reason = 1;
}
message TransactionCommitted {
}
message TransactionFinalized {
}

enum TransactionType {
    // Send claims from one party to another
    SEND = 0;
    // A request to convert fiat into claims
    CREATE_REQUEST = 1;
    // A request to convert claims into fiat
    REDEEM_REQUEST = 2;
    // Issued by the trust when fulfilling a `CreateRequest`
    CASH_CONFIRMATION = 3;
    // Issued by the trust when a `RedeemRequest` has been fulfilled
    REDEEM_FULFILLMENT = 4;
    // Issued by the trust to cancel pending create requests
    CREATE_CANCELLATION = 7;
    // Issued to add a CIDR block to the allowlist
    ALLOWLIST_CIDR_BLOCK = 8;
    // Issued to remove a CIDR block from the allowlist
    REMOVE_CIDR_BLOCK = 9;
    // Issued by root to register members
    REGISTER_ACCOUNT_AS_MEMBER = 10;
    // Issued by root to set the identity of the trust
    SET_TRUST = 11;
    // Issued by root to add a new keypair for a validator which may participate in consensus
    ADD_AUTHORITY_KEY = 12;
    // Issued by root to remove a keypair for an existing validator
    REMOVE_AUTHORITY_KEY = 13;
    // Issued by root to add a CIDR block to the allowlist
    ROOT_ALLOWLIST_CIDR_BLOCK = 14;
    // Issued by root to remove a CIDR block from the allowlist
    ROOT_REMOVE_ALLOWLIST_CIDR_BLOCK = 15;
    // Issued by trust to set how long pending create requests are valid before they expire
    SET_PENDING_CREATE_REQUEST_EXPIRE = 16;
    // Issued by member or validator, issuer not included
    SUBMIT_PROPOSAL = 17;
    // Issued by member or validator as a vote on specific proposal
    VOTE_PROPOSAL = 18;
    // Issued to cancel pending redeem requests
    REDEEM_CANCELLATION = 21;
    // Update runtime code
    RUNTIME_UPGRADE = 22;
    // Mark Member for Removal
    REMOVE_MEMBER = 23;
    // Issued by member to set own encryption key
    SET_MEMBER_ENCRYPTION_KEY = 24;
    // Issued by trust to set own encryption key
    SET_TRUST_ENCRYPTION_KEY = 25;
    // Issued by a validator to register its session keys
    REGISTER_SESSION_KEYS = 28;
    // Issued by root to set the identity of the limited agent
    SET_LIMITED_AGENT = 29;
    // Set the emission rate for validator payments
    SET_VALIDATOR_EMISSION_RATE = 30;
    // Immediately Exit Member
    EXIT_MEMBER = 31;
    // Network Withdrawal
    WITHDRAW_FROM_NETWORK = 32;
}

// Unix timestamp in milliseconds
message Timestamp {
    int64 unix_time_millis = 1;
}

// Allowlist entry returned by GetAllowlist
message AllowlistEntry {
    // The SS58 public key address the block is allowlisted for.
    string address = 2;
    // Cidr block allowlisted for this address. In X.X.X.X/X format.
    string cidr_block = 1;
}

// Query the list of members
message MembersRequest {}

// List of members
message Members {
    // SS58 public key addresses
    repeated string members = 1;
}

// Query the list of authority keys (validators)
message AuthorityKeysRequest {}

// List of authority keys (validators)
message AuthorityKeys {
    // SS58 public key addresses
    repeated string authority_keys = 1;
}

// Fetch the encryption key registered to a given account
message EncryptionKeyRequest {
    // The SS58 primary key of the account
    string address = 1;
}

message EncryptionKey {
    string public_key = 1;
}