World.cs 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  1. #pragma warning disable CS1591
  2. using System;
  3. using System.Collections.Generic;
  4. using System.Linq;
  5. using System.Text;
  6. using Solana.Unity.Programs;
  7. using Solana.Unity.Wallet;
  8. using Solana.Unity.Rpc.Models;
  9. using GplSession.Program;
  10. namespace World
  11. {
  12. namespace Program
  13. {
  14. public partial class WorldProgram
  15. {
  16. public static Solana.Unity.Rpc.Models.TransactionInstruction AddEntity(AddEntityAccounts accounts, PublicKey programId = null)
  17. {
  18. programId ??= new(ID);
  19. return AddEntity(accounts, (byte[]) null, programId);
  20. }
  21. public static Solana.Unity.Rpc.Models.TransactionInstruction AddEntity(AddEntityAccounts accounts, string extraSeed, PublicKey programId = null)
  22. {
  23. programId ??= new(ID);
  24. return AddEntity(accounts, System.Text.Encoding.UTF8.GetBytes(extraSeed), programId);
  25. }
  26. public static PublicKey FindCpiAuthPda() {
  27. PublicKey.TryFindProgramAddress(new[]
  28. {
  29. Encoding.UTF8.GetBytes("cpi_auth"),
  30. }, new PublicKey(ID), out var pda, out _);
  31. return pda;
  32. }
  33. public static PublicKey FindBufferPda(PublicKey account) {
  34. return FindBufferPda(account, new PublicKey(ID));
  35. }
  36. public static PublicKey FindSessionTokenPda(PublicKey sessionSigner, PublicKey authority)
  37. {
  38. PublicKey.TryFindProgramAddress(new[]
  39. {
  40. Encoding.UTF8.GetBytes("session_token"),
  41. new PublicKey(WorldProgram.ID).KeyBytes,
  42. sessionSigner.KeyBytes,
  43. authority.KeyBytes
  44. }, new PublicKey(GplSessionProgram.ID), out var pda, out _);
  45. return pda;
  46. }
  47. public static PublicKey FindRegistryPda()
  48. {
  49. PublicKey.TryFindProgramAddress(new[]
  50. {
  51. Encoding.UTF8.GetBytes("registry"),
  52. }, new PublicKey(ID), out var pda, out _);
  53. return pda;
  54. }
  55. public static PublicKey FindWorldPda(UInt64 worldId)
  56. {
  57. PublicKey.TryFindProgramAddress(new[]
  58. {
  59. Encoding.UTF8.GetBytes("world"),
  60. BitConverter.GetBytes(worldId).Reverse().ToArray()
  61. }, new PublicKey(ID), out var pda, out _);
  62. return pda;
  63. }
  64. public static PublicKey FindEntityPda(UInt64 worldId, UInt64 entityId)
  65. {
  66. PublicKey.TryFindProgramAddress(new[]
  67. {
  68. Encoding.UTF8.GetBytes("entity"),
  69. BitConverter.GetBytes(worldId).Reverse().ToArray(),
  70. BitConverter.GetBytes(entityId).Reverse().ToArray()
  71. }, new PublicKey(ID), out var pda, out _);
  72. return pda;
  73. }
  74. public static PublicKey FindEntityPda(UInt64 worldId, byte[] seed)
  75. {
  76. var ZeroArray = new byte[8];
  77. Array.Fill(ZeroArray, (byte) 0);
  78. PublicKey.TryFindProgramAddress(new[]
  79. {
  80. Encoding.UTF8.GetBytes("entity"),
  81. BitConverter.GetBytes(worldId).Reverse().ToArray(),
  82. ZeroArray,
  83. seed
  84. }, new PublicKey(ID), out var pda, out _);
  85. return pda;
  86. }
  87. public static PublicKey FindEntityPda(UInt64 worldId, string seed)
  88. {
  89. return FindEntityPda(worldId, System.Text.Encoding.UTF8.GetBytes(seed));
  90. }
  91. public static PublicKey FindComponentProgramDataPda(PublicKey componentProgramId)
  92. {
  93. PublicKey.TryFindProgramAddress(new[]
  94. {
  95. componentProgramId.KeyBytes,
  96. }, new PublicKey("BPFLoaderUpgradeab1e11111111111111111111111"), out var pda, out _);
  97. return pda;
  98. }
  99. public static PublicKey FindComponentPda(
  100. PublicKey componentProgramId,
  101. PublicKey entity
  102. ) {
  103. return FindComponentPda(componentProgramId, entity, "");
  104. }
  105. public static PublicKey FindComponentPda(
  106. PublicKey componentProgramId,
  107. PublicKey entity,
  108. string seed
  109. ) {
  110. return FindComponentPda(componentProgramId, entity, System.Text.Encoding.UTF8.GetBytes(seed));
  111. }
  112. public static PublicKey FindComponentPda(
  113. PublicKey componentProgramId,
  114. PublicKey entity,
  115. byte[] seed)
  116. {
  117. PublicKey.TryFindProgramAddress(new[]
  118. {
  119. seed, entity.KeyBytes
  120. }, componentProgramId, out var pda, out _);
  121. return pda;
  122. }
  123. public static readonly PublicKey DelegationProgram = new("DELeGGvXpWV2fqJUhqcF5ZSYMS4JTLjteaAMARRSaeSh");
  124. public static PublicKey FindDelegationProgramPda(string seed, PublicKey account)
  125. {
  126. PublicKey.TryFindProgramAddress(new[]
  127. {
  128. Encoding.UTF8.GetBytes(seed), account.KeyBytes
  129. }, DelegationProgram, out var pda, out _);
  130. return pda;
  131. }
  132. public static PublicKey FindBufferPda(PublicKey account, PublicKey owner)
  133. {
  134. PublicKey.TryFindProgramAddress(new[]
  135. {
  136. Encoding.UTF8.GetBytes("buffer"), account.KeyBytes
  137. }, owner, out var pda, out _);
  138. return pda;
  139. }
  140. /// <summary>
  141. /// Convenience bundle for defining an entity and the associated components.
  142. /// </summary>
  143. [Obsolete("Use Bolt.World.EntityType instead.")]
  144. public class EntityType{
  145. public PublicKey[] Components { get; set; }
  146. public string[] Seeds { get; set; }
  147. public PublicKey Entity { get; set; }
  148. public EntityType(PublicKey entity, PublicKey[] componentsIds)
  149. {
  150. Components = componentsIds;
  151. Seeds = new string[Components.Length];
  152. Entity = entity;
  153. Array.Fill(Seeds, "");
  154. }
  155. public EntityType(PublicKey entity, PublicKey[] componentsIds, string[] seeds)
  156. {
  157. Components = componentsIds;
  158. Seeds = seeds;
  159. Entity = entity;
  160. if (Seeds.Length != Components.Length)
  161. {
  162. throw new ArgumentException("Seeds must be the same length as components");
  163. }
  164. }
  165. public int ComponentsLength()
  166. {
  167. return Components.Length;
  168. }
  169. public PublicKey[] GetComponentsIds()
  170. {
  171. return Components;
  172. }
  173. public PublicKey[] GetComponentsPdas()
  174. {
  175. PublicKey[] pdas = new PublicKey[Components.Length];
  176. for (int i = 0; i < Components.Length; i++)
  177. {
  178. pdas[i] = FindComponentPda(Components[i], Entity, Seeds[i]);
  179. }
  180. return pdas;
  181. }
  182. }
  183. [Obsolete("Use Bolt.World.ApplySystem instead.")]
  184. public static Solana.Unity.Rpc.Models.TransactionInstruction ApplySystem(
  185. PublicKey world,
  186. PublicKey system,
  187. EntityType[] systemInput,
  188. byte[] args,
  189. PublicKey authority,
  190. PublicKey sessionToken = null,
  191. PublicKey programId = null)
  192. {
  193. programId ??= new(WorldProgram.ID);
  194. List<PublicKey> componentIds = new List<PublicKey>();
  195. List<PublicKey> componentPdas = new List<PublicKey>();
  196. foreach (var entity in systemInput)
  197. {
  198. componentIds.AddRange(entity.GetComponentsIds());
  199. componentPdas.AddRange(entity.GetComponentsPdas());
  200. }
  201. if (componentIds.Count != componentPdas.Count)
  202. {
  203. throw new ArgumentException("Component IDs and PDAs must be the same length");
  204. }
  205. Solana.Unity.Rpc.Models.TransactionInstruction instruction;
  206. if (sessionToken != null) {
  207. var apply = new ApplyWithSessionAccounts() {
  208. CpiAuth = WorldProgram.FindCpiAuthPda(),
  209. Buffer = FindBufferPda(componentPdas[0]),
  210. BoltSystem = system,
  211. Authority = authority,
  212. World = world,
  213. SessionToken = sessionToken,
  214. };
  215. instruction = ApplyWithSession(apply, args, programId);
  216. } else {
  217. var apply = new ApplyAccounts() {
  218. CpiAuth = WorldProgram.FindCpiAuthPda(),
  219. Buffer = FindBufferPda(componentPdas[0]),
  220. BoltSystem = system,
  221. Authority = authority,
  222. World = world,
  223. };
  224. instruction = Apply(apply, args, programId);
  225. }
  226. for (int i = 0; i < componentIds.Count; i++) {
  227. instruction.Keys.Add(AccountMeta.ReadOnly(componentIds[i], false));
  228. instruction.Keys.Add(AccountMeta.Writable(componentPdas[i], false));
  229. }
  230. if (componentIds.Count > 0) {
  231. // program id delimits the end of the component list
  232. instruction.Keys.Add(AccountMeta.ReadOnly(new PublicKey(WorldProgram.ID), false));
  233. }
  234. return instruction;
  235. }
  236. }
  237. }
  238. }