@typesol/cli 0.25.0 → 0.27.0

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.
Files changed (48) hide show
  1. package/CHANGELOG.md +39 -0
  2. package/README.md +32 -14
  3. package/SECURITY.md +2 -0
  4. package/dist/cli.js +52 -37
  5. package/dist/compiler/analyze.js +62 -5
  6. package/dist/compiler/emit/base.d.ts +2 -0
  7. package/dist/compiler/emit/base.js +4 -1
  8. package/dist/compiler/emit/calls.d.ts +16 -1
  9. package/dist/compiler/emit/calls.js +129 -1
  10. package/dist/compiler/emit/expressions.js +18 -0
  11. package/dist/compiler/emit/function.js +28 -0
  12. package/dist/compiler/emit/shared.js +2 -0
  13. package/dist/compiler/emit/storage.js +18 -0
  14. package/dist/compiler/model.d.ts +12 -0
  15. package/dist/compiler/model.js +3 -0
  16. package/dist/templates.js +1 -1
  17. package/dist/testing.d.ts +1 -1
  18. package/dist/testing.js +1 -1
  19. package/dist/{clientgen.js → tools/clientgen.js} +1 -1
  20. package/dist/tools/doctor.d.ts +45 -0
  21. package/dist/tools/doctor.js +229 -0
  22. package/dist/{portgen.js → tools/portgen.js} +1 -1
  23. package/dist/workspace.js +1 -1
  24. package/docs/architecture.md +17 -17
  25. package/docs/audit.md +90 -0
  26. package/docs/case-study-escrow.md +4 -4
  27. package/docs/cli.md +3 -2
  28. package/docs/errors.md +1 -1
  29. package/docs/language.md +7 -2
  30. package/docs/migrate-from-anchor.md +4 -0
  31. package/docs/runtime.md +1 -1
  32. package/docs/security-model.md +105 -0
  33. package/docs/testing.md +5 -4
  34. package/lib/typesol.d.ts +55 -1
  35. package/package.json +13 -13
  36. package/runtime/typesol_rt.h +82 -21
  37. /package/dist/{clientgen.d.ts → tools/clientgen.d.ts} +0 -0
  38. /package/dist/{cpigen.d.ts → tools/cpigen.d.ts} +0 -0
  39. /package/dist/{cpigen.js → tools/cpigen.js} +0 -0
  40. /package/dist/{idlpublish.d.ts → tools/idlpublish.d.ts} +0 -0
  41. /package/dist/{idlpublish.js → tools/idlpublish.js} +0 -0
  42. /package/dist/{onchain.d.ts → tools/onchain.d.ts} +0 -0
  43. /package/dist/{onchain.js → tools/onchain.js} +0 -0
  44. /package/dist/{portgen.d.ts → tools/portgen.d.ts} +0 -0
  45. /package/dist/{profile.d.ts → tools/profile.d.ts} +0 -0
  46. /package/dist/{profile.js → tools/profile.js} +0 -0
  47. /package/dist/{svmrpc.d.ts → tools/svmrpc.d.ts} +0 -0
  48. /package/dist/{svmrpc.js → tools/svmrpc.js} +0 -0
@@ -1121,6 +1121,81 @@ static inline bool ts_merkle_verify(const SolPubkey *leaf, const uint8_t *proof,
1121
1121
  return ts_mem_eq(node, root, 32);
1122
1122
  }
1123
1123
 
1124
+ /*
1125
+ * The Instructions sysvar: u16 count, u16 offsets[count], then per instruction u16 num_accounts,
1126
+ * num_accounts * (u8 flags: bit 0 signer, bit 1 writable; 32-byte key), 32-byte program id, u16 data_len, data; the
1127
+ * last two bytes of the account are the index of the instruction being executed. Everything here is the transaction
1128
+ * author's data: bounds-checked, never trusted for anything but what it says.
1129
+ */
1130
+ typedef struct {
1131
+ const uint8_t *accounts; /* num_accounts * 33 bytes */
1132
+ const SolPubkey *program_id;
1133
+ const uint8_t *data;
1134
+ uint16_t num_accounts;
1135
+ uint16_t data_len;
1136
+ } TsIx;
1137
+
1138
+ /* Instruction `index` of the transaction; false when out of range or malformed. */
1139
+ static inline bool ts_ix_at(const TsAccount *ixs, uint64_t index, TsIx *out) {
1140
+ const uint8_t *d = ixs->data;
1141
+ uint64_t len = ixs->data_len;
1142
+ if (len < 2) return false;
1143
+ uint16_t count;
1144
+ ts_memcpy(&count, d, 2);
1145
+ if (index >= count || 2 + (uint64_t)count * 2 > len) return false;
1146
+ uint16_t at;
1147
+ ts_memcpy(&at, d + 2 + index * 2, 2);
1148
+ uint64_t p = at;
1149
+ if (p + 2 > len) return false;
1150
+ ts_memcpy(&out->num_accounts, d + p, 2);
1151
+ p += 2;
1152
+ out->accounts = d + p;
1153
+ p += (uint64_t)out->num_accounts * 33;
1154
+ if (p + 34 > len) return false;
1155
+ out->program_id = (const SolPubkey *)(d + p);
1156
+ p += 32;
1157
+ ts_memcpy(&out->data_len, d + p, 2);
1158
+ p += 2;
1159
+ if (p + out->data_len > len) return false;
1160
+ out->data = d + p;
1161
+ return true;
1162
+ }
1163
+ static inline uint64_t ts_ix_load(const TsAccount *ixs, uint64_t index, TsIx *out) {
1164
+ if (!ts_ix_at(ixs, index, out)) TS_FAIL(TS_ERR_INDEX, "TypeSOL: no such instruction in the transaction");
1165
+ return SUCCESS;
1166
+ }
1167
+ static inline uint64_t ts_ix_count(const TsAccount *ixs, uint64_t *out) {
1168
+ if (ixs->data_len < 2) TS_FAIL(TS_ERR_INDEX, "TypeSOL: empty instructions sysvar");
1169
+ uint16_t n;
1170
+ ts_memcpy(&n, ixs->data, 2);
1171
+ *out = n;
1172
+ return SUCCESS;
1173
+ }
1174
+ static inline uint64_t ts_ix_current(const TsAccount *ixs, uint64_t *out) {
1175
+ if (ixs->data_len < 4) TS_FAIL(TS_ERR_INDEX, "TypeSOL: empty instructions sysvar");
1176
+ uint16_t i;
1177
+ ts_memcpy(&i, ixs->data + ixs->data_len - 2, 2);
1178
+ *out = i;
1179
+ return SUCCESS;
1180
+ }
1181
+ static inline uint64_t ts_ix_account(const TsIx *ix, uint64_t i, const uint8_t **out) {
1182
+ if (i >= ix->num_accounts) TS_FAIL(TS_ERR_INDEX, "TypeSOL: the instruction has no account at that index");
1183
+ *out = ix->accounts + i * 33;
1184
+ return SUCCESS;
1185
+ }
1186
+ /* `n` bytes of the instruction's data at `off` (little-endian integers, keys). */
1187
+ static inline uint64_t ts_ix_read(const TsIx *ix, uint64_t off, uint64_t n, void *out) {
1188
+ if (off > ix->data_len || n > ix->data_len - off) TS_FAIL(TS_ERR_INDEX, "TypeSOL: read past the end of the instruction's data");
1189
+ ts_memcpy(out, ix->data + off, n);
1190
+ return SUCCESS;
1191
+ }
1192
+ /* Is it `program`'s instruction with this 8-byte discriminator (Anchor's sha256("global:<name>")[..8])? */
1193
+ static inline bool ts_ix_is(const TsIx *ix, const SolPubkey *program, const uint8_t disc[8]) {
1194
+ return ts_key_eq(ix->program_id, program) && ix->data_len >= 8 && ts_mem_eq(ix->data, disc, 8);
1195
+ }
1196
+ /* How deep in CPIs the program runs: 1 when the transaction calls it directly. */
1197
+ extern uint64_t sol_get_stack_height(void);
1198
+
1124
1199
  /*
1125
1200
  * Did an Ed25519 precompile instruction in this transaction verify `message` signed by `signer`?
1126
1201
  * Reads the Instructions sysvar (data: u16 count, u16 offsets[count], then per instruction
@@ -1129,29 +1204,15 @@ static inline bool ts_merkle_verify(const SolPubkey *leaf, const uint8_t *proof,
1129
1204
  * message, with offsets pointing into the precompile's own data (instruction index 0xFFFF).
1130
1205
  */
1131
1206
  static inline bool ts_ed25519_verified(const TsAccount *ixs, const SolPubkey *signer, TS_Str message) {
1132
- const uint8_t *d = ixs->data;
1133
- uint64_t len = ixs->data_len;
1134
- if (len < 2) return false;
1207
+ if (ixs->data_len < 2) return false;
1135
1208
  uint16_t count;
1136
- ts_memcpy(&count, d, 2);
1137
- if (2 + (uint64_t)count * 2 > len) return false;
1209
+ ts_memcpy(&count, ixs->data, 2);
1138
1210
  for (uint16_t i = 0; i < count; i++) {
1139
- uint16_t at;
1140
- ts_memcpy(&at, d + 2 + (uint64_t)i * 2, 2);
1141
- uint64_t p = at;
1142
- if (p + 2 > len) return false;
1143
- uint16_t nacc;
1144
- ts_memcpy(&nacc, d + p, 2);
1145
- p += 2 + (uint64_t)nacc * 33;
1146
- if (p + 34 > len) return false;
1147
- bool is_ed = ts_mem_eq(d + p, &TS_ED25519_PROGRAM_ID, 32);
1148
- p += 32;
1149
- uint16_t dlen;
1150
- ts_memcpy(&dlen, d + p, 2);
1151
- p += 2;
1152
- if (p + dlen > len) return false;
1153
- if (!is_ed || dlen < 2) continue;
1154
- const uint8_t *ix = d + p;
1211
+ TsIx t;
1212
+ if (!ts_ix_at(ixs, i, &t)) return false;
1213
+ if (!ts_key_eq(t.program_id, &TS_ED25519_PROGRAM_ID) || t.data_len < 2) continue;
1214
+ uint16_t dlen = t.data_len;
1215
+ const uint8_t *ix = t.data;
1155
1216
  uint8_t nsig = ix[0];
1156
1217
  for (uint8_t k = 0; k < nsig; k++) {
1157
1218
  uint64_t o = 2 + (uint64_t)k * 14;
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes