@agent-shield/sdk 0.5.2 → 0.5.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/idl-json.js CHANGED
@@ -1,9 +1,6 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.IDL = void 0;
4
- // Auto-generated — do not edit. Regenerate with:
5
- // RUSTUP_TOOLCHAIN=nightly anchor idl build -o target/idl/agent_shield.json
6
- // Then copy JSON into this file.
7
4
  exports.IDL = {
8
5
  address: "4ZeVCqnjUgUtFrHHPG7jELUxvJeoVGHhGNgPrhBPwrHL",
9
6
  metadata: {
@@ -17,8 +14,7 @@ exports.IDL = {
17
14
  name: "agent_transfer",
18
15
  docs: [
19
16
  "Transfer tokens from the vault to an allowed destination.",
20
- "Only the agent can call this. Respects destination allowlist,",
21
- "spending caps, and per-token limits.",
17
+ "Only the agent can call this.",
22
18
  ],
23
19
  discriminator: [199, 111, 151, 49, 124, 13, 150, 44],
24
20
  accounts: [
@@ -48,7 +44,7 @@ exports.IDL = {
48
44
  },
49
45
  ],
50
46
  },
51
- relations: ["policy", "tracker"],
47
+ relations: ["policy"],
52
48
  },
53
49
  {
54
50
  name: "policy",
@@ -67,6 +63,7 @@ exports.IDL = {
67
63
  },
68
64
  {
69
65
  name: "tracker",
66
+ docs: ["Zero-copy SpendTracker"],
70
67
  writable: true,
71
68
  pda: {
72
69
  seeds: [
@@ -81,23 +78,38 @@ exports.IDL = {
81
78
  ],
82
79
  },
83
80
  },
81
+ {
82
+ name: "oracle_registry",
83
+ docs: ["Protocol-level oracle registry"],
84
+ pda: {
85
+ seeds: [
86
+ {
87
+ kind: "const",
88
+ value: [
89
+ 111, 114, 97, 99, 108, 101, 95, 114, 101, 103, 105, 115, 116,
90
+ 114, 121,
91
+ ],
92
+ },
93
+ ],
94
+ },
95
+ },
84
96
  {
85
97
  name: "vault_token_account",
86
98
  docs: ["Vault's PDA-owned token account (source)"],
87
99
  writable: true,
88
100
  },
101
+ {
102
+ name: "token_mint_account",
103
+ docs: ["Token mint account for decimals validation"],
104
+ },
89
105
  {
90
106
  name: "destination_token_account",
91
- docs: [
92
- "Destination token account (must be in allowed destinations if configured)",
93
- ],
107
+ docs: ["Destination token account (must be in allowed destinations)"],
94
108
  writable: true,
95
109
  },
96
110
  {
97
111
  name: "fee_destination_token_account",
98
- docs: [
99
- "Developer fee destination token account \u2014 must match vault.fee_destination",
100
- ],
112
+ docs: ["Developer fee destination token account"],
101
113
  writable: true,
102
114
  optional: true,
103
115
  },
@@ -121,10 +133,7 @@ exports.IDL = {
121
133
  },
122
134
  {
123
135
  name: "apply_pending_policy",
124
- docs: [
125
- "Apply a queued policy update after the timelock period has expired.",
126
- "Closes the PendingPolicyUpdate PDA and returns rent to the owner.",
127
- ],
136
+ docs: ["Apply a queued policy update after the timelock expires."],
128
137
  discriminator: [114, 212, 19, 227, 89, 199, 74, 62],
129
138
  accounts: [
130
139
  {
@@ -152,7 +161,7 @@ exports.IDL = {
152
161
  },
153
162
  ],
154
163
  },
155
- relations: ["policy", "tracker", "pending_policy"],
164
+ relations: ["policy", "pending_policy"],
156
165
  },
157
166
  {
158
167
  name: "policy",
@@ -170,22 +179,6 @@ exports.IDL = {
170
179
  ],
171
180
  },
172
181
  },
173
- {
174
- name: "tracker",
175
- writable: true,
176
- pda: {
177
- seeds: [
178
- {
179
- kind: "const",
180
- value: [116, 114, 97, 99, 107, 101, 114],
181
- },
182
- {
183
- kind: "account",
184
- path: "vault",
185
- },
186
- ],
187
- },
188
- },
189
182
  {
190
183
  name: "pending_policy",
191
184
  writable: true,
@@ -210,10 +203,7 @@ exports.IDL = {
210
203
  },
211
204
  {
212
205
  name: "cancel_pending_policy",
213
- docs: [
214
- "Cancel a queued policy update. Closes the PendingPolicyUpdate PDA",
215
- "and returns rent to the owner.",
216
- ],
206
+ docs: ["Cancel a queued policy update."],
217
207
  discriminator: [153, 36, 104, 200, 50, 94, 207, 33],
218
208
  accounts: [
219
209
  {
@@ -267,10 +257,7 @@ exports.IDL = {
267
257
  },
268
258
  {
269
259
  name: "close_vault",
270
- docs: [
271
- "Close the vault entirely. Withdraws all remaining funds and closes all PDAs.",
272
- "Reclaims rent. Vault must have no open positions. Only the owner can call this.",
273
- ],
260
+ docs: ["Close the vault entirely. Reclaims rent from all PDAs."],
274
261
  discriminator: [141, 103, 17, 126, 72, 75, 29, 29],
275
262
  accounts: [
276
263
  {
@@ -299,7 +286,7 @@ exports.IDL = {
299
286
  },
300
287
  ],
301
288
  },
302
- relations: ["policy", "tracker"],
289
+ relations: ["policy"],
303
290
  },
304
291
  {
305
292
  name: "policy",
@@ -319,6 +306,7 @@ exports.IDL = {
319
306
  },
320
307
  {
321
308
  name: "tracker",
309
+ docs: ["Zero-copy SpendTracker \u2014 close returns rent to owner"],
322
310
  writable: true,
323
311
  pda: {
324
312
  seeds: [
@@ -467,9 +455,7 @@ exports.IDL = {
467
455
  name: "finalize_session",
468
456
  docs: [
469
457
  "Finalize a session after the DeFi action completes.",
470
- "Revokes token delegation, collects fees, closes the SessionAuthority PDA,",
471
- "and records the transaction in the audit log.",
472
- "Can be called by the agent or permissionlessly (for cleanup of expired sessions).",
458
+ "Revokes delegation, collects fees, closes the SessionAuthority PDA.",
473
459
  ],
474
460
  discriminator: [34, 148, 144, 47, 37, 130, 206, 161],
475
461
  accounts: [
@@ -499,7 +485,7 @@ exports.IDL = {
499
485
  },
500
486
  ],
501
487
  },
502
- relations: ["policy", "tracker", "session"],
488
+ relations: ["policy", "session"],
503
489
  },
504
490
  {
505
491
  name: "policy",
@@ -516,27 +502,10 @@ exports.IDL = {
516
502
  ],
517
503
  },
518
504
  },
519
- {
520
- name: "tracker",
521
- writable: true,
522
- pda: {
523
- seeds: [
524
- {
525
- kind: "const",
526
- value: [116, 114, 97, 99, 107, 101, 114],
527
- },
528
- {
529
- kind: "account",
530
- path: "vault",
531
- },
532
- ],
533
- },
534
- },
535
505
  {
536
506
  name: "session",
537
507
  docs: [
538
- "Session rent is returned to the session's agent (who paid for it),",
539
- "not the arbitrary payer, to prevent rent theft.",
508
+ "Session rent is returned to the session's agent (who paid for it).",
540
509
  "Seeds include token_mint for per-token concurrent sessions.",
541
510
  ],
542
511
  writable: true,
@@ -565,30 +534,23 @@ exports.IDL = {
565
534
  },
566
535
  {
567
536
  name: "session_rent_recipient",
568
- docs: ["Validated in handler to equal session.agent."],
569
537
  writable: true,
570
538
  },
571
539
  {
572
540
  name: "vault_token_account",
573
- docs: [
574
- "Vault's PDA token account for the session's token (fee source + delegation revocation)",
575
- ],
541
+ docs: ["Vault's PDA token account for the session's token"],
576
542
  writable: true,
577
543
  optional: true,
578
544
  },
579
545
  {
580
546
  name: "fee_destination_token_account",
581
- docs: [
582
- "Developer fee destination token account \u2014 must match vault.fee_destination",
583
- ],
547
+ docs: ["Developer fee destination token account"],
584
548
  writable: true,
585
549
  optional: true,
586
550
  },
587
551
  {
588
552
  name: "protocol_treasury_token_account",
589
- docs: [
590
- "Protocol treasury token account \u2014 must be owned by PROTOCOL_TREASURY",
591
- ],
553
+ docs: ["Protocol treasury token account"],
592
554
  writable: true,
593
555
  optional: true,
594
556
  },
@@ -608,12 +570,58 @@ exports.IDL = {
608
570
  },
609
571
  ],
610
572
  },
573
+ {
574
+ name: "initialize_oracle_registry",
575
+ docs: [
576
+ "Initialize the protocol-level oracle registry.",
577
+ "Only called once. The authority becomes the registry admin.",
578
+ ],
579
+ discriminator: [190, 92, 228, 114, 56, 71, 101, 220],
580
+ accounts: [
581
+ {
582
+ name: "authority",
583
+ writable: true,
584
+ signer: true,
585
+ },
586
+ {
587
+ name: "oracle_registry",
588
+ writable: true,
589
+ pda: {
590
+ seeds: [
591
+ {
592
+ kind: "const",
593
+ value: [
594
+ 111, 114, 97, 99, 108, 101, 95, 114, 101, 103, 105, 115, 116,
595
+ 114, 121,
596
+ ],
597
+ },
598
+ ],
599
+ },
600
+ },
601
+ {
602
+ name: "system_program",
603
+ address: "11111111111111111111111111111111",
604
+ },
605
+ ],
606
+ args: [
607
+ {
608
+ name: "entries",
609
+ type: {
610
+ vec: {
611
+ defined: {
612
+ name: "OracleEntry",
613
+ },
614
+ },
615
+ },
616
+ },
617
+ ],
618
+ },
611
619
  {
612
620
  name: "initialize_vault",
613
621
  docs: [
614
622
  "Initialize a new agent vault with policy configuration.",
615
- "Only the owner can call this. Creates vault PDA, policy PDA, and spend tracker PDA.",
616
- "`tracker_tier`: 0 = Standard (200 entries), 1 = Pro (500), 2 = Max (1000).",
623
+ "Only the owner can call this. Creates vault PDA, policy PDA,",
624
+ "and zero-copy spend tracker PDA.",
617
625
  ],
618
626
  discriminator: [48, 191, 163, 44, 71, 129, 63, 164],
619
627
  accounts: [
@@ -660,6 +668,7 @@ exports.IDL = {
660
668
  },
661
669
  {
662
670
  name: "tracker",
671
+ docs: ["Zero-copy SpendTracker \u2014 2,352 bytes fixed size"],
663
672
  writable: true,
664
673
  pda: {
665
674
  seeds: [
@@ -676,7 +685,6 @@ exports.IDL = {
676
685
  },
677
686
  {
678
687
  name: "fee_destination",
679
- docs: ["The protocol treasury that receives fees"],
680
688
  },
681
689
  {
682
690
  name: "system_program",
@@ -697,17 +705,11 @@ exports.IDL = {
697
705
  type: "u64",
698
706
  },
699
707
  {
700
- name: "allowed_tokens",
701
- type: {
702
- vec: {
703
- defined: {
704
- name: "AllowedToken",
705
- },
706
- },
707
- },
708
+ name: "protocol_mode",
709
+ type: "u8",
708
710
  },
709
711
  {
710
- name: "allowed_protocols",
712
+ name: "protocols",
711
713
  type: {
712
714
  vec: "pubkey",
713
715
  },
@@ -734,19 +736,11 @@ exports.IDL = {
734
736
  vec: "pubkey",
735
737
  },
736
738
  },
737
- {
738
- name: "tracker_tier",
739
- type: "u8",
740
- },
741
739
  ],
742
740
  },
743
741
  {
744
742
  name: "queue_policy_update",
745
- docs: [
746
- "Queue a policy update when timelock is active.",
747
- "Creates a PendingPolicyUpdate PDA that becomes executable after",
748
- "the timelock period expires.",
749
- ],
743
+ docs: ["Queue a policy update when timelock is active."],
750
744
  discriminator: [149, 18, 76, 197, 179, 193, 91, 77],
751
745
  accounts: [
752
746
  {
@@ -829,19 +823,13 @@ exports.IDL = {
829
823
  },
830
824
  },
831
825
  {
832
- name: "allowed_tokens",
826
+ name: "protocol_mode",
833
827
  type: {
834
- option: {
835
- vec: {
836
- defined: {
837
- name: "AllowedToken",
838
- },
839
- },
840
- },
828
+ option: "u8",
841
829
  },
842
830
  },
843
831
  {
844
- name: "allowed_protocols",
832
+ name: "protocols",
845
833
  type: {
846
834
  option: {
847
835
  vec: "pubkey",
@@ -890,10 +878,7 @@ exports.IDL = {
890
878
  },
891
879
  {
892
880
  name: "reactivate_vault",
893
- docs: [
894
- "Reactivate a frozen vault. Optionally rotate the agent key.",
895
- "Only the owner can call this.",
896
- ],
881
+ docs: ["Reactivate a frozen vault. Optionally rotate the agent key."],
897
882
  discriminator: [245, 50, 143, 70, 114, 220, 25, 251],
898
883
  accounts: [
899
884
  {
@@ -977,8 +962,8 @@ exports.IDL = {
977
962
  {
978
963
  name: "revoke_agent",
979
964
  docs: [
980
- "Kill switch. Immediately freezes the vault, preventing all agent actions.",
981
- "Only the owner can call this. Funds can still be withdrawn by the owner.",
965
+ "Kill switch. Immediately freezes the vault.",
966
+ "Only the owner can call this.",
982
967
  ],
983
968
  discriminator: [227, 60, 209, 125, 240, 117, 163, 73],
984
969
  accounts: [
@@ -1011,12 +996,58 @@ exports.IDL = {
1011
996
  ],
1012
997
  args: [],
1013
998
  },
999
+ {
1000
+ name: "update_oracle_registry",
1001
+ docs: [
1002
+ "Add or remove entries from the oracle registry.",
1003
+ "Only the registry authority can call this.",
1004
+ ],
1005
+ discriminator: [184, 234, 19, 21, 41, 240, 100, 14],
1006
+ accounts: [
1007
+ {
1008
+ name: "authority",
1009
+ signer: true,
1010
+ },
1011
+ {
1012
+ name: "oracle_registry",
1013
+ writable: true,
1014
+ pda: {
1015
+ seeds: [
1016
+ {
1017
+ kind: "const",
1018
+ value: [
1019
+ 111, 114, 97, 99, 108, 101, 95, 114, 101, 103, 105, 115, 116,
1020
+ 114, 121,
1021
+ ],
1022
+ },
1023
+ ],
1024
+ },
1025
+ },
1026
+ ],
1027
+ args: [
1028
+ {
1029
+ name: "entries_to_add",
1030
+ type: {
1031
+ vec: {
1032
+ defined: {
1033
+ name: "OracleEntry",
1034
+ },
1035
+ },
1036
+ },
1037
+ },
1038
+ {
1039
+ name: "mints_to_remove",
1040
+ type: {
1041
+ vec: "pubkey",
1042
+ },
1043
+ },
1044
+ ],
1045
+ },
1014
1046
  {
1015
1047
  name: "update_policy",
1016
1048
  docs: [
1017
1049
  "Update the policy configuration for a vault.",
1018
- "Only the owner can call this. Cannot be called by the agent.",
1019
- "Blocked when timelock_duration > 0 \u2014 use queue_policy_update instead.",
1050
+ "Only the owner can call this. Blocked when timelock > 0.",
1020
1051
  ],
1021
1052
  discriminator: [212, 245, 246, 7, 163, 151, 18, 57],
1022
1053
  accounts: [
@@ -1044,7 +1075,7 @@ exports.IDL = {
1044
1075
  },
1045
1076
  ],
1046
1077
  },
1047
- relations: ["policy", "tracker"],
1078
+ relations: ["policy"],
1048
1079
  },
1049
1080
  {
1050
1081
  name: "policy",
@@ -1062,22 +1093,6 @@ exports.IDL = {
1062
1093
  ],
1063
1094
  },
1064
1095
  },
1065
- {
1066
- name: "tracker",
1067
- writable: true,
1068
- pda: {
1069
- seeds: [
1070
- {
1071
- kind: "const",
1072
- value: [116, 114, 97, 99, 107, 101, 114],
1073
- },
1074
- {
1075
- kind: "account",
1076
- path: "vault",
1077
- },
1078
- ],
1079
- },
1080
- },
1081
1096
  ],
1082
1097
  args: [
1083
1098
  {
@@ -1093,19 +1108,13 @@ exports.IDL = {
1093
1108
  },
1094
1109
  },
1095
1110
  {
1096
- name: "allowed_tokens",
1111
+ name: "protocol_mode",
1097
1112
  type: {
1098
- option: {
1099
- vec: {
1100
- defined: {
1101
- name: "AllowedToken",
1102
- },
1103
- },
1104
- },
1113
+ option: "u8",
1105
1114
  },
1106
1115
  },
1107
1116
  {
1108
- name: "allowed_protocols",
1117
+ name: "protocols",
1109
1118
  type: {
1110
1119
  option: {
1111
1120
  vec: "pubkey",
@@ -1156,10 +1165,8 @@ exports.IDL = {
1156
1165
  name: "validate_and_authorize",
1157
1166
  docs: [
1158
1167
  "Core permission check. Called by the agent before a DeFi action.",
1159
- "Validates the action against all policy constraints (USD caps, per-token caps).",
1160
- "If approved, creates a SessionAuthority PDA, delegates tokens to agent,",
1161
- "and updates spend tracking.",
1162
- "If denied, reverts the entire transaction (including subsequent DeFi instructions).",
1168
+ "Validates against policy constraints + oracle registry.",
1169
+ "Creates a SessionAuthority PDA, delegates tokens to agent.",
1163
1170
  ],
1164
1171
  discriminator: [22, 183, 48, 222, 218, 11, 197, 152],
1165
1172
  accounts: [
@@ -1189,7 +1196,7 @@ exports.IDL = {
1189
1196
  },
1190
1197
  ],
1191
1198
  },
1192
- relations: ["policy", "tracker"],
1199
+ relations: ["policy"],
1193
1200
  },
1194
1201
  {
1195
1202
  name: "policy",
@@ -1208,6 +1215,7 @@ exports.IDL = {
1208
1215
  },
1209
1216
  {
1210
1217
  name: "tracker",
1218
+ docs: ["Zero-copy SpendTracker"],
1211
1219
  writable: true,
1212
1220
  pda: {
1213
1221
  seeds: [
@@ -1222,6 +1230,21 @@ exports.IDL = {
1222
1230
  ],
1223
1231
  },
1224
1232
  },
1233
+ {
1234
+ name: "oracle_registry",
1235
+ docs: ["Protocol-level oracle registry (shared across all vaults)"],
1236
+ pda: {
1237
+ seeds: [
1238
+ {
1239
+ kind: "const",
1240
+ value: [
1241
+ 111, 114, 97, 99, 108, 101, 95, 114, 101, 103, 105, 115, 116,
1242
+ 114, 121,
1243
+ ],
1244
+ },
1245
+ ],
1246
+ },
1247
+ },
1225
1248
  {
1226
1249
  name: "session",
1227
1250
  docs: [
@@ -1252,9 +1275,7 @@ exports.IDL = {
1252
1275
  },
1253
1276
  {
1254
1277
  name: "vault_token_account",
1255
- docs: [
1256
- "Vault's PDA-owned token account for the spend token (delegation source)",
1257
- ],
1278
+ docs: ["Vault's PDA-owned token account for the spend token"],
1258
1279
  writable: true,
1259
1280
  },
1260
1281
  {
@@ -1301,10 +1322,7 @@ exports.IDL = {
1301
1322
  },
1302
1323
  {
1303
1324
  name: "withdraw_funds",
1304
- docs: [
1305
- "Withdraw tokens from the vault back to the owner.",
1306
- "Works in any vault status (Active or Frozen). Only the owner can call this.",
1307
- ],
1325
+ docs: ["Withdraw tokens from the vault back to the owner."],
1308
1326
  discriminator: [241, 36, 29, 111, 208, 31, 104, 217],
1309
1327
  accounts: [
1310
1328
  {
@@ -1420,6 +1438,10 @@ exports.IDL = {
1420
1438
  name: "AgentVault",
1421
1439
  discriminator: [232, 220, 237, 164, 157, 9, 215, 194],
1422
1440
  },
1441
+ {
1442
+ name: "OracleRegistry",
1443
+ discriminator: [94, 153, 19, 250, 94, 0, 12, 172],
1444
+ },
1423
1445
  {
1424
1446
  name: "PendingPolicyUpdate",
1425
1447
  discriminator: [77, 255, 2, 51, 79, 237, 183, 239],
@@ -1442,10 +1464,6 @@ exports.IDL = {
1442
1464
  name: "ActionAuthorized",
1443
1465
  discriminator: [85, 90, 59, 218, 126, 8, 179, 63],
1444
1466
  },
1445
- {
1446
- name: "ActionDenied",
1447
- discriminator: [243, 239, 240, 51, 151, 100, 10, 100],
1448
- },
1449
1467
  {
1450
1468
  name: "AgentRegistered",
1451
1469
  discriminator: [191, 78, 217, 54, 232, 100, 189, 85],
@@ -1474,6 +1492,14 @@ exports.IDL = {
1474
1492
  name: "FundsWithdrawn",
1475
1493
  discriminator: [56, 130, 230, 154, 35, 92, 11, 118],
1476
1494
  },
1495
+ {
1496
+ name: "OracleRegistryInitialized",
1497
+ discriminator: [88, 111, 7, 92, 74, 14, 114, 205],
1498
+ },
1499
+ {
1500
+ name: "OracleRegistryUpdated",
1501
+ discriminator: [25, 85, 137, 57, 175, 133, 14, 77],
1502
+ },
1477
1503
  {
1478
1504
  name: "PolicyChangeApplied",
1479
1505
  discriminator: [104, 89, 5, 100, 180, 202, 52, 73],
@@ -1525,13 +1551,13 @@ exports.IDL = {
1525
1551
  },
1526
1552
  {
1527
1553
  code: 6003,
1528
- name: "TokenNotAllowed",
1529
- msg: "Token not in allowed list",
1554
+ name: "TokenNotRegistered",
1555
+ msg: "Token not registered in oracle registry",
1530
1556
  },
1531
1557
  {
1532
1558
  code: 6004,
1533
1559
  name: "ProtocolNotAllowed",
1534
- msg: "Protocol not in allowed list",
1560
+ msg: "Protocol not allowed by policy",
1535
1561
  },
1536
1562
  {
1537
1563
  code: 6005,
@@ -1580,163 +1606,163 @@ exports.IDL = {
1580
1606
  },
1581
1607
  {
1582
1608
  code: 6014,
1583
- name: "TooManyAllowedTokens",
1584
- msg: "Policy configuration invalid: too many allowed tokens",
1585
- },
1586
- {
1587
- code: 6015,
1588
1609
  name: "TooManyAllowedProtocols",
1589
1610
  msg: "Policy configuration invalid: too many allowed protocols",
1590
1611
  },
1591
1612
  {
1592
- code: 6016,
1613
+ code: 6015,
1593
1614
  name: "AgentAlreadyRegistered",
1594
1615
  msg: "Agent already registered for this vault",
1595
1616
  },
1596
1617
  {
1597
- code: 6017,
1618
+ code: 6016,
1598
1619
  name: "NoAgentRegistered",
1599
1620
  msg: "No agent registered for this vault",
1600
1621
  },
1601
1622
  {
1602
- code: 6018,
1623
+ code: 6017,
1603
1624
  name: "VaultNotFrozen",
1604
1625
  msg: "Vault is not frozen (expected frozen for reactivation)",
1605
1626
  },
1606
1627
  {
1607
- code: 6019,
1628
+ code: 6018,
1608
1629
  name: "VaultAlreadyClosed",
1609
1630
  msg: "Vault is already closed",
1610
1631
  },
1611
1632
  {
1612
- code: 6020,
1633
+ code: 6019,
1613
1634
  name: "InsufficientBalance",
1614
1635
  msg: "Insufficient vault balance for withdrawal",
1615
1636
  },
1616
1637
  {
1617
- code: 6021,
1638
+ code: 6020,
1618
1639
  name: "DeveloperFeeTooHigh",
1619
1640
  msg: "Developer fee rate exceeds maximum (500 / 1,000,000 = 5 BPS)",
1620
1641
  },
1621
1642
  {
1622
- code: 6022,
1643
+ code: 6021,
1623
1644
  name: "InvalidFeeDestination",
1624
1645
  msg: "Fee destination account invalid",
1625
1646
  },
1626
1647
  {
1627
- code: 6023,
1648
+ code: 6022,
1628
1649
  name: "InvalidProtocolTreasury",
1629
1650
  msg: "Protocol treasury account does not match expected address",
1630
1651
  },
1631
1652
  {
1632
- code: 6024,
1633
- name: "TooManySpendEntries",
1634
- msg: "Spend entry limit reached (too many active entries in rolling window)",
1635
- },
1636
- {
1637
- code: 6025,
1653
+ code: 6023,
1638
1654
  name: "InvalidAgentKey",
1639
1655
  msg: "Invalid agent: cannot be the zero address",
1640
1656
  },
1641
1657
  {
1642
- code: 6026,
1658
+ code: 6024,
1643
1659
  name: "AgentIsOwner",
1644
1660
  msg: "Invalid agent: agent cannot be the vault owner",
1645
1661
  },
1646
1662
  {
1647
- code: 6027,
1663
+ code: 6025,
1648
1664
  name: "Overflow",
1649
1665
  msg: "Arithmetic overflow",
1650
1666
  },
1651
1667
  {
1652
- code: 6028,
1668
+ code: 6026,
1653
1669
  name: "DelegationFailed",
1654
1670
  msg: "Token delegation approval failed",
1655
1671
  },
1656
1672
  {
1657
- code: 6029,
1673
+ code: 6027,
1658
1674
  name: "RevocationFailed",
1659
1675
  msg: "Token delegation revocation failed",
1660
1676
  },
1661
1677
  {
1662
- code: 6030,
1678
+ code: 6028,
1663
1679
  name: "OracleFeedStale",
1664
1680
  msg: "Oracle feed value is too stale",
1665
1681
  },
1666
1682
  {
1667
- code: 6031,
1683
+ code: 6029,
1668
1684
  name: "OracleFeedInvalid",
1669
1685
  msg: "Cannot parse oracle feed data",
1670
1686
  },
1671
1687
  {
1672
- code: 6032,
1688
+ code: 6030,
1673
1689
  name: "TokenSpendBlocked",
1674
1690
  msg: "Unpriced token cannot be spent (receive-only)",
1675
1691
  },
1676
1692
  {
1677
- code: 6033,
1693
+ code: 6031,
1678
1694
  name: "InvalidTokenAccount",
1679
1695
  msg: "Token account does not belong to vault or has wrong mint",
1680
1696
  },
1681
1697
  {
1682
- code: 6034,
1698
+ code: 6032,
1683
1699
  name: "OracleAccountMissing",
1684
1700
  msg: "Oracle-priced token requires feed account in remaining_accounts",
1685
1701
  },
1686
1702
  {
1687
- code: 6035,
1688
- name: "PerTokenCapExceeded",
1689
- msg: "Per-token daily spending cap would be exceeded",
1703
+ code: 6033,
1704
+ name: "OracleConfidenceTooWide",
1705
+ msg: "Oracle price confidence interval too wide",
1690
1706
  },
1691
1707
  {
1692
- code: 6036,
1693
- name: "PerTokenTxLimitExceeded",
1694
- msg: "Per-token single transaction limit exceeded",
1695
- },
1696
- {
1697
- code: 6037,
1698
- name: "OracleConfidenceTooWide",
1699
- msg: "Oracle price confidence interval too wide",
1700
- },
1701
- {
1702
- code: 6038,
1708
+ code: 6034,
1703
1709
  name: "OracleUnsupportedType",
1704
1710
  msg: "Oracle account owner is not a recognized oracle program",
1705
1711
  },
1706
1712
  {
1707
- code: 6039,
1713
+ code: 6035,
1708
1714
  name: "OracleNotVerified",
1709
1715
  msg: "Pyth price update not fully verified by Wormhole",
1710
1716
  },
1711
1717
  {
1712
- code: 6040,
1718
+ code: 6036,
1713
1719
  name: "TimelockNotExpired",
1714
1720
  msg: "Timelock period has not expired yet",
1715
1721
  },
1716
1722
  {
1717
- code: 6041,
1723
+ code: 6037,
1718
1724
  name: "TimelockActive",
1719
1725
  msg: "Vault has timelock active \u2014 use queue_policy_update instead",
1720
1726
  },
1721
1727
  {
1722
- code: 6042,
1728
+ code: 6038,
1723
1729
  name: "NoTimelockConfigured",
1724
1730
  msg: "No timelock configured on this vault",
1725
1731
  },
1726
1732
  {
1727
- code: 6043,
1733
+ code: 6039,
1728
1734
  name: "DestinationNotAllowed",
1729
1735
  msg: "Destination not in allowed list",
1730
1736
  },
1731
1737
  {
1732
- code: 6044,
1738
+ code: 6040,
1733
1739
  name: "TooManyDestinations",
1734
1740
  msg: "Too many destinations (max 10)",
1735
1741
  },
1742
+ {
1743
+ code: 6041,
1744
+ name: "InvalidProtocolMode",
1745
+ msg: "Invalid protocol mode (must be 0, 1, or 2)",
1746
+ },
1747
+ {
1748
+ code: 6042,
1749
+ name: "OracleRegistryFull",
1750
+ msg: "Oracle registry is full (max 105 entries)",
1751
+ },
1752
+ {
1753
+ code: 6043,
1754
+ name: "UnauthorizedRegistryAdmin",
1755
+ msg: "Unauthorized: not the oracle registry authority",
1756
+ },
1757
+ {
1758
+ code: 6044,
1759
+ name: "OraclePriceDivergence",
1760
+ msg: "Primary and fallback oracle prices diverge beyond threshold",
1761
+ },
1736
1762
  {
1737
1763
  code: 6045,
1738
- name: "InvalidTrackerTier",
1739
- msg: "Invalid tracker tier (must be 0, 1, or 2)",
1764
+ name: "OracleBothFeedsFailed",
1765
+ msg: "Both primary and fallback oracle feeds failed",
1740
1766
  },
1741
1767
  ],
1742
1768
  types: [
@@ -1808,30 +1834,6 @@ exports.IDL = {
1808
1834
  ],
1809
1835
  },
1810
1836
  },
1811
- {
1812
- name: "ActionDenied",
1813
- type: {
1814
- kind: "struct",
1815
- fields: [
1816
- {
1817
- name: "vault",
1818
- type: "pubkey",
1819
- },
1820
- {
1821
- name: "agent",
1822
- type: "pubkey",
1823
- },
1824
- {
1825
- name: "reason",
1826
- type: "string",
1827
- },
1828
- {
1829
- name: "timestamp",
1830
- type: "i64",
1831
- },
1832
- ],
1833
- },
1834
- },
1835
1837
  {
1836
1838
  name: "ActionType",
1837
1839
  docs: ["Action types that agents can request"],
@@ -1949,10 +1951,8 @@ exports.IDL = {
1949
1951
  {
1950
1952
  name: "fee_destination",
1951
1953
  docs: [
1952
- "Developer fee destination \u2014 the wallet that receives developer fees",
1953
- "on every finalized transaction. IMMUTABLE after initialization \u2014 only",
1954
- "`initialize_vault` writes this field. This prevents a compromised owner",
1955
- "key from redirecting fees. Protocol fees go to PROTOCOL_TREASURY separately.",
1954
+ "Developer fee destination \u2014 IMMUTABLE after initialization.",
1955
+ "Prevents a compromised owner from redirecting fees.",
1956
1956
  ],
1957
1957
  type: "pubkey",
1958
1958
  },
@@ -2002,91 +2002,55 @@ exports.IDL = {
2002
2002
  {
2003
2003
  name: "total_fees_collected",
2004
2004
  docs: [
2005
- "Cumulative developer fees collected from this vault (token base units).",
2006
- "Protocol fees are tracked separately via events.",
2005
+ "Cumulative developer fees collected from this vault (token base units)",
2007
2006
  ],
2008
2007
  type: "u64",
2009
2008
  },
2010
- {
2011
- name: "tracker_tier",
2012
- docs: ["Tracker capacity tier chosen at vault creation"],
2013
- type: {
2014
- defined: {
2015
- name: "TrackerTier",
2016
- },
2017
- },
2018
- },
2019
2009
  ],
2020
2010
  },
2021
2011
  },
2022
2012
  {
2023
- name: "AllowedToken",
2024
- docs: [
2025
- "Per-token configuration including oracle feed and per-token caps.",
2026
- "Replaces the old `Vec<Pubkey>` allowed_tokens with richer metadata.",
2027
- "",
2028
- "Oracle feed classification:",
2029
- "- `Pubkey::default()` = stablecoin (1:1 USD, no oracle needed)",
2030
- "- `UNPRICED_SENTINEL` ([0xFF; 32]) = unpriced token (receive-only)",
2031
- "- Any other pubkey = Oracle feed account (Pyth PriceUpdateV2 or Switchboard PullFeed)",
2032
- ],
2013
+ name: "DelegationRevoked",
2033
2014
  type: {
2034
2015
  kind: "struct",
2035
2016
  fields: [
2036
2017
  {
2037
- name: "mint",
2038
- docs: ["Token mint address"],
2018
+ name: "vault",
2039
2019
  type: "pubkey",
2040
2020
  },
2041
2021
  {
2042
- name: "oracle_feed",
2043
- docs: [
2044
- "Oracle feed account (Pyth PriceUpdateV2 or Switchboard PullFeed) for USD pricing.",
2045
- "`Pubkey::default()` = stablecoin (1:1 USD).",
2046
- "`UNPRICED_SENTINEL` = unpriced (receive-only, cannot be spent).",
2047
- ],
2022
+ name: "token_account",
2048
2023
  type: "pubkey",
2049
2024
  },
2050
2025
  {
2051
- name: "decimals",
2052
- docs: ["Token decimals (e.g., 6 for USDC, 9 for SOL)"],
2053
- type: "u8",
2054
- },
2055
- {
2056
- name: "daily_cap_base",
2057
- docs: [
2058
- "Per-token daily cap in base units (0 = no per-token limit,",
2059
- "only the aggregate USD cap applies)",
2060
- ],
2061
- type: "u64",
2062
- },
2063
- {
2064
- name: "max_tx_base",
2065
- docs: [
2066
- "Per-token max single transaction in base units",
2067
- "(0 = no per-token tx limit, only USD tx limit applies)",
2068
- ],
2069
- type: "u64",
2026
+ name: "timestamp",
2027
+ type: "i64",
2070
2028
  },
2071
2029
  ],
2072
2030
  },
2073
2031
  },
2074
2032
  {
2075
- name: "DelegationRevoked",
2033
+ name: "EpochBucket",
2034
+ docs: [
2035
+ "A single epoch bucket tracking aggregate USD spend.",
2036
+ "16 bytes per bucket. USD-only \u2014 rate limiting stays client-side.",
2037
+ ],
2038
+ serialization: "bytemuck",
2039
+ repr: {
2040
+ kind: "c",
2041
+ },
2076
2042
  type: {
2077
2043
  kind: "struct",
2078
2044
  fields: [
2079
2045
  {
2080
- name: "vault",
2081
- type: "pubkey",
2082
- },
2083
- {
2084
- name: "token_account",
2085
- type: "pubkey",
2046
+ name: "epoch_id",
2047
+ docs: ["Epoch identifier: unix_timestamp / EPOCH_DURATION"],
2048
+ type: "i64",
2086
2049
  },
2087
2050
  {
2088
- name: "timestamp",
2089
- type: "i64",
2051
+ name: "usd_amount",
2052
+ docs: ["Aggregate USD spent in this epoch (6 decimals)"],
2053
+ type: "u64",
2090
2054
  },
2091
2055
  ],
2092
2056
  },
@@ -2195,6 +2159,116 @@ exports.IDL = {
2195
2159
  ],
2196
2160
  },
2197
2161
  },
2162
+ {
2163
+ name: "OracleEntry",
2164
+ docs: ["Individual entry mapping a token mint to its oracle feed."],
2165
+ type: {
2166
+ kind: "struct",
2167
+ fields: [
2168
+ {
2169
+ name: "mint",
2170
+ docs: ["SPL token mint address"],
2171
+ type: "pubkey",
2172
+ },
2173
+ {
2174
+ name: "oracle_feed",
2175
+ docs: [
2176
+ "Pyth or Switchboard oracle feed account.",
2177
+ "Ignored when is_stablecoin is true.",
2178
+ ],
2179
+ type: "pubkey",
2180
+ },
2181
+ {
2182
+ name: "is_stablecoin",
2183
+ docs: ["If true, token is 1:1 USD (no oracle read needed)"],
2184
+ type: "bool",
2185
+ },
2186
+ {
2187
+ name: "fallback_feed",
2188
+ docs: [
2189
+ "Optional fallback oracle feed. Pubkey::default() = no fallback.",
2190
+ "Used when primary is stale/invalid. Cross-checked for divergence",
2191
+ "when both are available.",
2192
+ ],
2193
+ type: "pubkey",
2194
+ },
2195
+ ],
2196
+ },
2197
+ },
2198
+ {
2199
+ name: "OracleRegistry",
2200
+ docs: [
2201
+ "Protocol-level oracle registry \u2014 maps token mints to oracle feeds.",
2202
+ "Maintained by protocol admin. Shared across ALL vaults.",
2203
+ "Any vault can use any registered token without per-vault configuration.",
2204
+ "",
2205
+ 'Seeds: `[b"oracle_registry"]`',
2206
+ ],
2207
+ type: {
2208
+ kind: "struct",
2209
+ fields: [
2210
+ {
2211
+ name: "authority",
2212
+ docs: [
2213
+ "Authority who can add/remove entries (upgradeable to multisig/DAO)",
2214
+ ],
2215
+ type: "pubkey",
2216
+ },
2217
+ {
2218
+ name: "entries",
2219
+ docs: ["Token mint \u2192 oracle feed mappings"],
2220
+ type: {
2221
+ vec: {
2222
+ defined: {
2223
+ name: "OracleEntry",
2224
+ },
2225
+ },
2226
+ },
2227
+ },
2228
+ {
2229
+ name: "bump",
2230
+ docs: ["Bump seed for PDA"],
2231
+ type: "u8",
2232
+ },
2233
+ ],
2234
+ },
2235
+ },
2236
+ {
2237
+ name: "OracleRegistryInitialized",
2238
+ type: {
2239
+ kind: "struct",
2240
+ fields: [
2241
+ {
2242
+ name: "authority",
2243
+ type: "pubkey",
2244
+ },
2245
+ {
2246
+ name: "entry_count",
2247
+ type: "u16",
2248
+ },
2249
+ ],
2250
+ },
2251
+ },
2252
+ {
2253
+ name: "OracleRegistryUpdated",
2254
+ type: {
2255
+ kind: "struct",
2256
+ fields: [
2257
+ {
2258
+ name: "added_count",
2259
+ type: "u16",
2260
+ },
2261
+ {
2262
+ name: "removed_count",
2263
+ type: "u16",
2264
+ },
2265
+ {
2266
+ name: "total_entries",
2267
+ type: "u16",
2268
+ },
2269
+ ],
2270
+ },
2271
+ },
2198
2272
  {
2199
2273
  name: "PendingPolicyUpdate",
2200
2274
  docs: [
@@ -2235,19 +2309,13 @@ exports.IDL = {
2235
2309
  },
2236
2310
  },
2237
2311
  {
2238
- name: "allowed_tokens",
2312
+ name: "protocol_mode",
2239
2313
  type: {
2240
- option: {
2241
- vec: {
2242
- defined: {
2243
- name: "AllowedToken",
2244
- },
2245
- },
2246
- },
2314
+ option: "u8",
2247
2315
  },
2248
2316
  },
2249
2317
  {
2250
- name: "allowed_protocols",
2318
+ name: "protocols",
2251
2319
  type: {
2252
2320
  option: {
2253
2321
  vec: "pubkey",
@@ -2368,24 +2436,20 @@ exports.IDL = {
2368
2436
  type: "u64",
2369
2437
  },
2370
2438
  {
2371
- name: "allowed_tokens",
2439
+ name: "protocol_mode",
2372
2440
  docs: [
2373
- "Allowed token mints with oracle feeds and per-token caps.",
2374
- "Bounded to MAX_ALLOWED_TOKENS entries.",
2441
+ "Protocol access control mode:",
2442
+ "0 = all allowed (protocols list ignored)",
2443
+ "1 = allowlist (only protocols in list)",
2444
+ "2 = denylist (all except protocols in list)",
2375
2445
  ],
2376
- type: {
2377
- vec: {
2378
- defined: {
2379
- name: "AllowedToken",
2380
- },
2381
- },
2382
- },
2446
+ type: "u8",
2383
2447
  },
2384
2448
  {
2385
- name: "allowed_protocols",
2449
+ name: "protocols",
2386
2450
  docs: [
2387
- "Allowed program IDs the agent can call (Jupiter, Flash Trade, etc.)",
2388
- "Bounded to MAX_ALLOWED_PROTOCOLS entries",
2451
+ "Protocol pubkeys for allowlist/denylist.",
2452
+ "Bounded to MAX_ALLOWED_PROTOCOLS entries.",
2389
2453
  ],
2390
2454
  type: {
2391
2455
  vec: "pubkey",
@@ -2394,7 +2458,7 @@ exports.IDL = {
2394
2458
  {
2395
2459
  name: "max_leverage_bps",
2396
2460
  docs: [
2397
- "Maximum leverage multiplier in basis points (e.g., 10000 = 100x, 1000 = 10x)",
2461
+ "Maximum leverage multiplier in basis points (e.g., 10000 = 100x)",
2398
2462
  "Set to 0 to disallow leveraged positions entirely",
2399
2463
  ],
2400
2464
  type: "u16",
@@ -2415,19 +2479,14 @@ exports.IDL = {
2415
2479
  name: "developer_fee_rate",
2416
2480
  docs: [
2417
2481
  "Developer fee rate (rate / 1,000,000). Applied to every finalized",
2418
- "transaction. Fee deducted from vault, transferred to vault's",
2419
- "fee_destination. Max MAX_DEVELOPER_FEE_RATE (500 = 5 BPS).",
2420
- "Set to 0 for no developer fee. Protocol fee is always applied",
2421
- "separately at PROTOCOL_FEE_RATE.",
2482
+ "transaction. Max MAX_DEVELOPER_FEE_RATE (500 = 5 BPS).",
2422
2483
  ],
2423
2484
  type: "u16",
2424
2485
  },
2425
2486
  {
2426
2487
  name: "timelock_duration",
2427
2488
  docs: [
2428
- "Timelock duration in seconds for policy changes. 0 = no timelock",
2429
- "(immediate updates allowed). When > 0, policy changes must go",
2430
- "through queue_policy_update \u2192 apply_pending_policy.",
2489
+ "Timelock duration in seconds for policy changes. 0 = no timelock.",
2431
2490
  ],
2432
2491
  type: "u64",
2433
2492
  },
@@ -2467,11 +2526,11 @@ exports.IDL = {
2467
2526
  type: "u64",
2468
2527
  },
2469
2528
  {
2470
- name: "allowed_tokens_count",
2529
+ name: "protocol_mode",
2471
2530
  type: "u8",
2472
2531
  },
2473
2532
  {
2474
- name: "allowed_protocols_count",
2533
+ name: "protocols_count",
2475
2534
  type: "u8",
2476
2535
  },
2477
2536
  {
@@ -2589,43 +2648,20 @@ exports.IDL = {
2589
2648
  ],
2590
2649
  },
2591
2650
  },
2592
- {
2593
- name: "SpendEntry",
2594
- type: {
2595
- kind: "struct",
2596
- fields: [
2597
- {
2598
- name: "token_index",
2599
- docs: [
2600
- "Index into PolicyConfig.allowed_tokens[] (0-9).",
2601
- "Compact representation \u2014 avoids storing full 32-byte Pubkey per entry.",
2602
- "Invalidated when token list changes (rolling_spends is cleared).",
2603
- ],
2604
- type: "u8",
2605
- },
2606
- {
2607
- name: "usd_amount",
2608
- docs: [
2609
- "USD value of this spend (6 decimals, e.g., $500 = 500_000_000)",
2610
- ],
2611
- type: "u64",
2612
- },
2613
- {
2614
- name: "base_amount",
2615
- docs: [
2616
- "Original amount in token base units (for per-token cap checks)",
2617
- ],
2618
- type: "u64",
2619
- },
2620
- {
2621
- name: "timestamp",
2622
- type: "i64",
2623
- },
2624
- ],
2625
- },
2626
- },
2627
2651
  {
2628
2652
  name: "SpendTracker",
2653
+ docs: [
2654
+ "Zero-copy 144-epoch circular buffer for rolling 24h USD spend tracking.",
2655
+ "Each bucket covers a 10-minute epoch. Boundary correction ensures",
2656
+ "functionally exact accuracy (~$0.000001 worst-case rounding).",
2657
+ "Rounding direction: slightly permissive (under-counts by at most $0.000001).",
2658
+ "",
2659
+ 'Seeds: `[b"tracker", vault.key().as_ref()]`',
2660
+ ],
2661
+ serialization: "bytemuck",
2662
+ repr: {
2663
+ kind: "c",
2664
+ },
2629
2665
  type: {
2630
2666
  kind: "struct",
2631
2667
  fields: [
@@ -2635,47 +2671,17 @@ exports.IDL = {
2635
2671
  type: "pubkey",
2636
2672
  },
2637
2673
  {
2638
- name: "tracker_tier",
2639
- docs: ["Tracker capacity tier (Standard/Pro/Max)"],
2640
- type: {
2641
- defined: {
2642
- name: "TrackerTier",
2643
- },
2644
- },
2645
- },
2646
- {
2647
- name: "max_spend_entries",
2648
- docs: [
2649
- "Maximum spend entries for this tracker (derived from tier at init)",
2650
- ],
2651
- type: "u32",
2652
- },
2653
- {
2654
- name: "rolling_spends",
2655
- docs: [
2656
- "Rolling spend entries: (token_mint, usd_amount, base_amount, timestamp)",
2657
- "Entries older than ROLLING_WINDOW_SECONDS are pruned on each access",
2658
- ],
2659
- type: {
2660
- vec: {
2661
- defined: {
2662
- name: "SpendEntry",
2663
- },
2664
- },
2665
- },
2666
- },
2667
- {
2668
- name: "recent_transactions",
2669
- docs: [
2670
- "Recent transaction log for on-chain audit trail",
2671
- "Bounded to MAX_RECENT_TRANSACTIONS, oldest entries evicted (ring buffer)",
2672
- ],
2674
+ name: "buckets",
2675
+ docs: ["144 epoch buckets for rolling 24h spend tracking"],
2673
2676
  type: {
2674
- vec: {
2675
- defined: {
2676
- name: "TransactionRecord",
2677
+ array: [
2678
+ {
2679
+ defined: {
2680
+ name: "EpochBucket",
2681
+ },
2677
2682
  },
2678
- },
2683
+ 144,
2684
+ ],
2679
2685
  },
2680
2686
  },
2681
2687
  {
@@ -2683,67 +2689,13 @@ exports.IDL = {
2683
2689
  docs: ["Bump seed for PDA"],
2684
2690
  type: "u8",
2685
2691
  },
2686
- ],
2687
- },
2688
- },
2689
- {
2690
- name: "TrackerTier",
2691
- docs: [
2692
- "Tracker capacity tiers \u2014 chosen at vault creation, determines",
2693
- "max rolling spend entries and SpendTracker account size.",
2694
- ],
2695
- type: {
2696
- kind: "enum",
2697
- variants: [
2698
- {
2699
- name: "Standard",
2700
- },
2701
2692
  {
2702
- name: "Pro",
2703
- },
2704
- {
2705
- name: "Max",
2706
- },
2707
- ],
2708
- },
2709
- },
2710
- {
2711
- name: "TransactionRecord",
2712
- type: {
2713
- kind: "struct",
2714
- fields: [
2715
- {
2716
- name: "timestamp",
2717
- type: "i64",
2718
- },
2719
- {
2720
- name: "action_type",
2693
+ name: "_padding",
2694
+ docs: ["Padding for 8-byte alignment"],
2721
2695
  type: {
2722
- defined: {
2723
- name: "ActionType",
2724
- },
2696
+ array: ["u8", 7],
2725
2697
  },
2726
2698
  },
2727
- {
2728
- name: "token_mint",
2729
- type: "pubkey",
2730
- },
2731
- {
2732
- name: "amount",
2733
- type: "u64",
2734
- },
2735
- {
2736
- name: "protocol",
2737
- type: "pubkey",
2738
- },
2739
- {
2740
- name: "success",
2741
- type: "bool",
2742
- },
2743
- {
2744
- name: "slot",
2745
- type: "u64",
2746
- },
2747
2699
  ],
2748
2700
  },
2749
2701
  },