@prb/effect-solana 1.0.0-beta.4 → 1.0.0-beta.5

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 (95) hide show
  1. package/README.md +48 -3
  2. package/dist/balance/service.d.ts +2 -2
  3. package/dist/balance/service.d.ts.map +1 -1
  4. package/dist/balance/service.js +3 -3
  5. package/dist/balance/service.js.map +1 -1
  6. package/dist/internal/kit-effect.d.ts +2 -2
  7. package/dist/internal/kit-effect.d.ts.map +1 -1
  8. package/dist/internal/kit-effect.js +1 -1
  9. package/dist/internal/kit-effect.js.map +1 -1
  10. package/dist/pda/service.js +1 -1
  11. package/dist/pda/service.js.map +1 -1
  12. package/dist/presets/layers.d.ts +10 -10
  13. package/dist/presets/layers.d.ts.map +1 -1
  14. package/dist/presets/layers.js +8 -8
  15. package/dist/presets/layers.js.map +1 -1
  16. package/dist/program/index.d.ts +1 -0
  17. package/dist/program/index.d.ts.map +1 -1
  18. package/dist/program/index.js +1 -0
  19. package/dist/program/index.js.map +1 -1
  20. package/dist/program/internal/anchor-helpers.d.ts +20 -0
  21. package/dist/program/internal/anchor-helpers.d.ts.map +1 -0
  22. package/dist/program/internal/anchor-helpers.js +64 -0
  23. package/dist/program/internal/anchor-helpers.js.map +1 -0
  24. package/dist/program/reader.d.ts +19 -0
  25. package/dist/program/reader.d.ts.map +1 -0
  26. package/dist/program/reader.js +288 -0
  27. package/dist/program/reader.js.map +1 -0
  28. package/dist/program/service.d.ts +1 -1
  29. package/dist/program/service.d.ts.map +1 -1
  30. package/dist/program/service.js +18 -37
  31. package/dist/program/service.js.map +1 -1
  32. package/dist/program/types.d.ts +48 -13
  33. package/dist/program/types.d.ts.map +1 -1
  34. package/dist/program/types.js +27 -28
  35. package/dist/program/types.js.map +1 -1
  36. package/dist/rpc/service.d.ts +2 -2
  37. package/dist/rpc/service.d.ts.map +1 -1
  38. package/dist/rpc/service.js +1 -1
  39. package/dist/rpc/service.js.map +1 -1
  40. package/dist/signer/service.d.ts +1 -1
  41. package/dist/signer/service.d.ts.map +1 -1
  42. package/dist/signer/service.js +2 -2
  43. package/dist/signer/service.js.map +1 -1
  44. package/dist/telemetry/tracer.d.ts +3 -0
  45. package/dist/telemetry/tracer.d.ts.map +1 -1
  46. package/dist/telemetry/tracer.js +3 -0
  47. package/dist/telemetry/tracer.js.map +1 -1
  48. package/dist/testing-kit/mock-balance-service.d.ts +2 -2
  49. package/dist/testing-kit/mock-balance-service.d.ts.map +1 -1
  50. package/dist/testing-kit/mock-balance-service.js +1 -1
  51. package/dist/testing-kit/mock-balance-service.js.map +1 -1
  52. package/dist/testing-kit/mock-pda-service.d.ts +2 -2
  53. package/dist/testing-kit/mock-pda-service.d.ts.map +1 -1
  54. package/dist/testing-kit/mock-pda-service.js +1 -1
  55. package/dist/testing-kit/mock-pda-service.js.map +1 -1
  56. package/dist/testing-kit/mock-rpc-service.d.ts +3 -3
  57. package/dist/testing-kit/mock-rpc-service.d.ts.map +1 -1
  58. package/dist/testing-kit/mock-rpc-service.js +2 -2
  59. package/dist/testing-kit/mock-rpc-service.js.map +1 -1
  60. package/dist/testing-kit/mock-signer-service.d.ts +3 -3
  61. package/dist/testing-kit/mock-signer-service.d.ts.map +1 -1
  62. package/dist/testing-kit/mock-signer-service.js +2 -2
  63. package/dist/testing-kit/mock-signer-service.js.map +1 -1
  64. package/dist/testing-kit/mock-token-service.d.ts +3 -3
  65. package/dist/testing-kit/mock-token-service.d.ts.map +1 -1
  66. package/dist/testing-kit/mock-token-service.js +1 -1
  67. package/dist/testing-kit/mock-token-service.js.map +1 -1
  68. package/dist/testing-kit/mock-transaction-service.d.ts +7 -8
  69. package/dist/testing-kit/mock-transaction-service.d.ts.map +1 -1
  70. package/dist/testing-kit/mock-transaction-service.js +1 -1
  71. package/dist/testing-kit/mock-transaction-service.js.map +1 -1
  72. package/dist/testing-kit/test-layer.d.ts +11 -7
  73. package/dist/testing-kit/test-layer.d.ts.map +1 -1
  74. package/dist/testing-kit/test-layer.js +12 -5
  75. package/dist/testing-kit/test-layer.js.map +1 -1
  76. package/dist/token/service.d.ts +2 -2
  77. package/dist/token/service.d.ts.map +1 -1
  78. package/dist/token/service.js +4 -4
  79. package/dist/token/service.js.map +1 -1
  80. package/dist/tx/service.d.ts +9 -10
  81. package/dist/tx/service.d.ts.map +1 -1
  82. package/dist/tx/service.js +4 -4
  83. package/dist/tx/service.js.map +1 -1
  84. package/dist/tx/types.d.ts +2 -0
  85. package/dist/tx/types.d.ts.map +1 -1
  86. package/dist/tx/types.js.map +1 -1
  87. package/dist/web3.js/layers.d.ts +9 -9
  88. package/dist/web3.js/layers.d.ts.map +1 -1
  89. package/dist/web3.js/layers.js +1 -1
  90. package/dist/web3.js/layers.js.map +1 -1
  91. package/dist/web3.js/legacy-signer.d.ts +1 -1
  92. package/dist/web3.js/legacy-signer.d.ts.map +1 -1
  93. package/dist/web3.js/legacy-signer.js +3 -3
  94. package/dist/web3.js/legacy-signer.js.map +1 -1
  95. package/package.json +19 -14
package/README.md CHANGED
@@ -3,6 +3,10 @@
3
3
  [![npm version](https://img.shields.io/npm/v/@prb/effect-solana.svg)](https://www.npmjs.com/package/@prb/effect-solana)
4
4
  [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
5
5
 
6
+ > [!WARNING]
7
+ >
8
+ > This is experimental, beta software. It is provided "as is" without warranty of any kind, express or implied.
9
+
6
10
  Effect-TS integration for the Solana blockchain ecosystem. Type-safe, composable abstractions built on
7
11
  [@solana/kit](https://github.com/solana-labs/solana-web3.js) v2.
8
12
 
@@ -210,6 +214,40 @@ const program = Effect.gen(function* () {
210
214
  });
211
215
  ```
212
216
 
217
+ ### ProgramReader
218
+
219
+ Read on-chain state via Anchor's `.view()` (signer-path reads).
220
+
221
+ `.view()` requires a connected wallet — Anchor uses the signer's publicKey as the payer for the simulated transaction.
222
+ For disconnected or low-balance wallets, use the simulator fallback path at the application level.
223
+
224
+ ```typescript
225
+ import { Effect } from "effect";
226
+ import { ProgramReader } from "@prb/effect-solana";
227
+ import type { Idl } from "@prb/effect-solana";
228
+
229
+ const program = Effect.gen(function* () {
230
+ const reader = yield* ProgramReader;
231
+
232
+ // Single read
233
+ const result = yield* reader.view({
234
+ idl,
235
+ method: "getWithdrawableAmount",
236
+ args: [streamId],
237
+ accounts: { stream, streamRecipient },
238
+ programId,
239
+ });
240
+
241
+ // Batched reads (reuse the program instance)
242
+ const anchorProgram = yield* reader.createProgram({ idl, programId });
243
+ const amount = yield* reader.viewWithProgram(anchorProgram, {
244
+ method: "getWithdrawableAmount",
245
+ args: [streamId],
246
+ accounts: { stream, streamRecipient },
247
+ });
248
+ });
249
+ ```
250
+
213
251
  ### PdaService
214
252
 
215
253
  Program Derived Address utilities.
@@ -244,6 +282,8 @@ const signerLayer = makeSignerLayer(() => walletAdapter);
244
282
  import { Layer } from "effect";
245
283
  import {
246
284
  BalanceServiceLive,
285
+ PdaServiceLive,
286
+ ProgramReaderLive,
247
287
  RpcService,
248
288
  SignerService,
249
289
  TokenServiceLive,
@@ -263,9 +303,14 @@ const MySignerLayer = Layer.succeed(SignerService, {
263
303
  });
264
304
 
265
305
  // Compose layers
266
- const AppLayer = Layer.mergeAll(BalanceServiceLive, TokenServiceLive, TransactionServiceLive, ProgramWriterLive).pipe(
267
- Layer.provide(Layer.merge(MyRpcLayer, MySignerLayer)),
268
- );
306
+ const AppLayer = Layer.mergeAll(
307
+ BalanceServiceLive,
308
+ TokenServiceLive,
309
+ TransactionServiceLive,
310
+ PdaServiceLive,
311
+ ProgramReaderLive,
312
+ ProgramWriterLive,
313
+ ).pipe(Layer.provide(Layer.merge(MyRpcLayer, MySignerLayer)));
269
314
  ```
270
315
 
271
316
  ## ⚛️ React Integration
@@ -1,7 +1,7 @@
1
1
  import type { Address, Lamports } from "@solana/kit";
2
2
  import { Context, Effect, Layer, Stream } from "effect";
3
- import { RpcError } from "../core/errors/index.js";
4
- import { RpcService } from "../rpc/index.js";
3
+ import { RpcError } from "#src/core/errors/index.js";
4
+ import { RpcService } from "#src/rpc/index.js";
5
5
  export type BalanceServiceShape = {
6
6
  readonly getSolBalance: (address: Address) => Effect.Effect<Lamports, RpcError>;
7
7
  readonly hasSufficientBalance: (params: {
@@ -1 +1 @@
1
- {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/balance/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,OAAO,EAAY,MAAM,EAAE,KAAK,EAAY,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAQhD,MAAM,MAAM,mBAAmB,GAAG;IAIhC,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAKhF,QAAQ,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE;QACtC,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,QAAQ,CAAC;KACpB,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAKvC,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE;QAC9B,OAAO,EAAE,OAAO,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;CACxD,CAAC;;AAOF,qBAAa,cAAe,SAAQ,mBAGjC;CAAG;AAON,eAAO,MAAM,kBAAkB,gDAgF9B,CAAC"}
1
+ {"version":3,"file":"service.d.ts","sourceRoot":"","sources":["../../src/balance/service.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,OAAO,EAAY,MAAM,EAAE,KAAK,EAAY,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,2BAA2B,CAAC;AACrD,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAQ/C,MAAM,MAAM,mBAAmB,GAAG;IAIhC,QAAQ,CAAC,aAAa,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;IAKhF,QAAQ,CAAC,oBAAoB,EAAE,CAAC,MAAM,EAAE;QACtC,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,QAAQ,CAAC;KACpB,KAAK,MAAM,CAAC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAKvC,QAAQ,CAAC,YAAY,EAAE,CAAC,MAAM,EAAE;QAC9B,OAAO,EAAE,OAAO,CAAC;QACjB,eAAe,CAAC,EAAE,MAAM,CAAC;KAC1B,KAAK,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC;CACxD,CAAC;;AAOF,qBAAa,cAAe,SAAQ,mBAGjC;CAAG;AAON,eAAO,MAAM,kBAAkB,gDAgF9B,CAAC"}
@@ -1,7 +1,7 @@
1
1
  import { Context, Duration, Effect, Layer, Schedule, Stream } from "effect";
2
- import { RpcError } from "../core/errors/index.js";
3
- import { RpcService } from "../rpc/index.js";
4
- import { SpanNames } from "../telemetry/index.js";
2
+ import { RpcError } from "#src/core/errors/index.js";
3
+ import { RpcService } from "#src/rpc/index.js";
4
+ import { SpanNames } from "#src/telemetry/index.js";
5
5
  export class BalanceService extends Context.Tag("esolana/BalanceService")() {
6
6
  }
7
7
  export const BalanceServiceLive = Layer.effect(BalanceService, Effect.gen(function* () {
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/balance/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAC5E,OAAO,EAAE,QAAQ,EAAE,MAAM,4BAA4B,CAAC;AACtD,OAAO,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AAmCrD,MAAM,OAAO,cAAe,SAAQ,OAAO,CAAC,GAAG,CAAC,wBAAwB,CAAC,EAGtE;CAAG;AAON,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAC5C,cAAc,EACd,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC;IAErC,OAAO,cAAc,CAAC,EAAE,CAAC;QACvB,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,CACzB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YAE7C,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;gBAC9B,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,QAAQ,CAAC;oBACX,KAAK;oBACL,OAAO,EAAE,6BAA6B,OAAO,EAAE;oBAC/C,GAAG,EAAE,MAAM;iBACZ,CAAC;gBACJ,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE;aAC1C,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,EACxC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE;YACzC,UAAU,EAAE,EAAE,OAAO,EAAE;SACxB,CAAC,CACH;QAEH,oBAAoB,EAAE,CAAC,MAAM,EAAE,EAAE,CAC/B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YAE7C,MAAM,QAAQ,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;gBACxC,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,QAAQ,CAAC;oBACX,KAAK;oBACL,OAAO,EAAE,6BAA6B,MAAM,CAAC,OAAO,EAAE;oBACtD,GAAG,EAAE,MAAM;iBACZ,CAAC;gBACJ,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE;aACjD,CAAC,CAAC;YAEH,OAAO,QAAQ,CAAC,KAAK,IAAI,MAAM,CAAC,QAAQ,CAAC;QAC3C,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE;YACzC,UAAU,EAAE;gBACV,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,QAAQ,EAAE,MAAM,CAAC,QAAQ,CAAC,QAAQ,EAAE;aACrC;SACF,CAAC,CACH;QAEH,YAAY,EAAE,CAAC,MAAM,EAAE,EAAE,CACvB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;YACvC,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC;YAC7C,MAAM,QAAQ,GAAG,MAAM,CAAC,eAAe,IAAI,IAAI,CAAC;YAEhD,OAAO,MAAM,CAAC,wBAAwB,CACpC,MAAM,CAAC,UAAU,CAAC;gBAChB,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,QAAQ,CAAC;oBACX,KAAK;oBACL,OAAO,EAAE,8BAA8B,MAAM,CAAC,OAAO,EAAE;oBACvD,GAAG,EAAE,MAAM;iBACZ,CAAC;gBACJ,GAAG,EAAE,GAAG,EAAE,CAAC,GAAG,CAAC,UAAU,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE;aACjD,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC,QAAQ,EAAE,EAAE,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,EACjD,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,MAAM,CAAC,QAAQ,CAAC,CAAC,CAC3C,CAAC;QACJ,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,iBAAiB,EAAE;YAC3C,UAAU,EAAE;gBACV,OAAO,EAAE,MAAM,CAAC,OAAO;gBACvB,eAAe,EAAE,MAAM,CAAC,eAAe;aACxC;SACF,CAAC,CACH;KACJ,CAAC,CAAC;AACL,CAAC,CAAC,CACH,CAAC","sourcesContent":["import type { Address, Lamports } from \"@solana/kit\";\nimport { Context, Duration, Effect, Layer, Schedule, Stream } from \"effect\";\nimport { RpcError } from \"@/src/core/errors/index.js\";\nimport { RpcService } from \"@/src/rpc/index.js\";\nimport { SpanNames } from \"@/src/telemetry/index.js\";\n\n/**\n * Shape of the Balance service for type inference.\n *\n * @category Services\n */\nexport type BalanceServiceShape = {\n /**\n * Get the SOL balance for an address.\n */\n readonly getSolBalance: (address: Address) => Effect.Effect<Lamports, RpcError>;\n\n /**\n * Check if an address has sufficient SOL balance.\n */\n readonly hasSufficientBalance: (params: {\n address: Address;\n required: Lamports;\n }) => Effect.Effect<boolean, RpcError>;\n\n /**\n * Watch SOL balance changes for an address.\n */\n readonly watchBalance: (params: {\n address: Address;\n pollingInterval?: number;\n }) => Effect.Effect<Stream.Stream<Lamports, RpcError>>;\n};\n\n/**\n * Service tag for Balance operations.\n *\n * @category Services\n */\nexport class BalanceService extends Context.Tag(\"esolana/BalanceService\")<\n BalanceService,\n BalanceServiceShape\n>() {}\n\n/**\n * Live implementation of the Balance service.\n *\n * @category Layers\n */\nexport const BalanceServiceLive = Layer.effect(\n BalanceService,\n Effect.gen(function* () {\n const rpcService = yield* RpcService;\n\n return BalanceService.of({\n getSolBalance: (address) =>\n Effect.gen(function* () {\n const rpc = yield* rpcService.getRpc();\n const rpcUrl = yield* rpcService.getRpcUrl();\n\n return yield* Effect.tryPromise({\n catch: (cause) =>\n new RpcError({\n cause,\n message: `Failed to get balance for ${address}`,\n url: rpcUrl,\n }),\n try: () => rpc.getBalance(address).send(),\n });\n }).pipe(\n Effect.map((response) => response.value),\n Effect.withSpan(SpanNames.BALANCE_GET_SOL, {\n attributes: { address },\n })\n ),\n\n hasSufficientBalance: (params) =>\n Effect.gen(function* () {\n const rpc = yield* rpcService.getRpc();\n const rpcUrl = yield* rpcService.getRpcUrl();\n\n const response = yield* Effect.tryPromise({\n catch: (cause) =>\n new RpcError({\n cause,\n message: `Failed to get balance for ${params.address}`,\n url: rpcUrl,\n }),\n try: () => rpc.getBalance(params.address).send(),\n });\n\n return response.value >= params.required;\n }).pipe(\n Effect.withSpan(SpanNames.BALANCE_GET_SOL, {\n attributes: {\n address: params.address,\n required: params.required.toString(),\n },\n })\n ),\n\n watchBalance: (params) =>\n Effect.gen(function* () {\n const rpc = yield* rpcService.getRpc();\n const rpcUrl = yield* rpcService.getRpcUrl();\n const interval = params.pollingInterval ?? 5000;\n\n return Stream.repeatEffectWithSchedule(\n Effect.tryPromise({\n catch: (cause) =>\n new RpcError({\n cause,\n message: `Failed to poll balance for ${params.address}`,\n url: rpcUrl,\n }),\n try: () => rpc.getBalance(params.address).send(),\n }).pipe(Effect.map((response) => response.value)),\n Schedule.spaced(Duration.millis(interval))\n );\n }).pipe(\n Effect.withSpan(SpanNames.BALANCE_WATCH_SOL, {\n attributes: {\n address: params.address,\n pollingInterval: params.pollingInterval,\n },\n })\n ),\n });\n })\n);\n"]}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/balance/service.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Address, Lamports } from \"@solana/kit\";\nimport { Context, Duration, Effect, Layer, Schedule, Stream } from \"effect\";\nimport { RpcError } from \"#src/core/errors/index.js\";\nimport { RpcService } from \"#src/rpc/index.js\";\nimport { SpanNames } from \"#src/telemetry/index.js\";\n\n/**\n * Shape of the Balance service for type inference.\n *\n * @category Services\n */\nexport type BalanceServiceShape = {\n /**\n * Get the SOL balance for an address.\n */\n readonly getSolBalance: (address: Address) => Effect.Effect<Lamports, RpcError>;\n\n /**\n * Check if an address has sufficient SOL balance.\n */\n readonly hasSufficientBalance: (params: {\n address: Address;\n required: Lamports;\n }) => Effect.Effect<boolean, RpcError>;\n\n /**\n * Watch SOL balance changes for an address.\n */\n readonly watchBalance: (params: {\n address: Address;\n pollingInterval?: number;\n }) => Effect.Effect<Stream.Stream<Lamports, RpcError>>;\n};\n\n/**\n * Service tag for Balance operations.\n *\n * @category Services\n */\nexport class BalanceService extends Context.Tag(\"esolana/BalanceService\")<\n BalanceService,\n BalanceServiceShape\n>() {}\n\n/**\n * Live implementation of the Balance service.\n *\n * @category Layers\n */\nexport const BalanceServiceLive = Layer.effect(\n BalanceService,\n Effect.gen(function* () {\n const rpcService = yield* RpcService;\n\n return BalanceService.of({\n getSolBalance: (address) =>\n Effect.gen(function* () {\n const rpc = yield* rpcService.getRpc();\n const rpcUrl = yield* rpcService.getRpcUrl();\n\n return yield* Effect.tryPromise({\n catch: (cause) =>\n new RpcError({\n cause,\n message: `Failed to get balance for ${address}`,\n url: rpcUrl,\n }),\n try: () => rpc.getBalance(address).send(),\n });\n }).pipe(\n Effect.map((response) => response.value),\n Effect.withSpan(SpanNames.BALANCE_GET_SOL, {\n attributes: { address },\n })\n ),\n\n hasSufficientBalance: (params) =>\n Effect.gen(function* () {\n const rpc = yield* rpcService.getRpc();\n const rpcUrl = yield* rpcService.getRpcUrl();\n\n const response = yield* Effect.tryPromise({\n catch: (cause) =>\n new RpcError({\n cause,\n message: `Failed to get balance for ${params.address}`,\n url: rpcUrl,\n }),\n try: () => rpc.getBalance(params.address).send(),\n });\n\n return response.value >= params.required;\n }).pipe(\n Effect.withSpan(SpanNames.BALANCE_GET_SOL, {\n attributes: {\n address: params.address,\n required: params.required.toString(),\n },\n })\n ),\n\n watchBalance: (params) =>\n Effect.gen(function* () {\n const rpc = yield* rpcService.getRpc();\n const rpcUrl = yield* rpcService.getRpcUrl();\n const interval = params.pollingInterval ?? 5000;\n\n return Stream.repeatEffectWithSchedule(\n Effect.tryPromise({\n catch: (cause) =>\n new RpcError({\n cause,\n message: `Failed to poll balance for ${params.address}`,\n url: rpcUrl,\n }),\n try: () => rpc.getBalance(params.address).send(),\n }).pipe(Effect.map((response) => response.value)),\n Schedule.spaced(Duration.millis(interval))\n );\n }).pipe(\n Effect.withSpan(SpanNames.BALANCE_WATCH_SOL, {\n attributes: {\n address: params.address,\n pollingInterval: params.pollingInterval,\n },\n })\n ),\n });\n })\n);\n"]}
@@ -1,7 +1,7 @@
1
1
  import type { Rpc, SolanaRpcApi } from "@solana/kit";
2
2
  import { Effect } from "effect";
3
- import { RpcError } from "../core/errors/rpc.js";
4
- import type { RpcServiceShape } from "../rpc/service.js";
3
+ import { RpcError } from "#src/core/errors/rpc.js";
4
+ import type { RpcServiceShape } from "#src/rpc/service.js";
5
5
  export declare const withRpc: <A, E, R>(rpcService: RpcServiceShape, fn: (rpc: Rpc<SolanaRpcApi>) => Effect.Effect<A, E, R>) => Effect.Effect<A, E, R>;
6
6
  export declare const kitTryPromise: <A, E>(operation: () => Promise<A>, classifier: (error: unknown) => E) => Effect.Effect<A, E>;
7
7
  export declare const classifyRpcError: (error: unknown, context: {
@@ -1 +1 @@
1
- {"version":3,"file":"kit-effect.d.ts","sourceRoot":"","sources":["../../src/internal/kit-effect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AACpD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAkB5D,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAC7B,YAAY,eAAe,EAC3B,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KACrD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAIpB,CAAC;AAeL,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAChC,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,YAAY,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,KAChC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAIjB,CAAC;AAKL,eAAO,MAAM,gBAAgB,GAC3B,OAAO,OAAO,EACd,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAC1C,QAOF,CAAC"}
1
+ {"version":3,"file":"kit-effect.d.ts","sourceRoot":"","sources":["../../src/internal/kit-effect.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AACnD,OAAO,KAAK,EAAE,eAAe,EAAE,MAAM,qBAAqB,CAAC;AAkB3D,eAAO,MAAM,OAAO,GAAI,CAAC,EAAE,CAAC,EAAE,CAAC,EAC7B,YAAY,eAAe,EAC3B,IAAI,CAAC,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KACrD,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAIpB,CAAC;AAeL,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,CAAC,EAChC,WAAW,MAAM,OAAO,CAAC,CAAC,CAAC,EAC3B,YAAY,CAAC,KAAK,EAAE,OAAO,KAAK,CAAC,KAChC,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAIjB,CAAC;AAKL,eAAO,MAAM,gBAAgB,GAC3B,OAAO,OAAO,EACd,SAAS;IAAE,GAAG,EAAE,MAAM,CAAC;IAAC,SAAS,EAAE,MAAM,CAAA;CAAE,KAC1C,QAOF,CAAC"}
@@ -1,5 +1,5 @@
1
1
  import { Effect } from "effect";
2
- import { RpcError } from "../core/errors/rpc.js";
2
+ import { RpcError } from "#src/core/errors/rpc.js";
3
3
  export const withRpc = (rpcService, fn) => Effect.gen(function* () {
4
4
  const rpc = yield* rpcService.getRpc();
5
5
  return yield* fn(rpc);
@@ -1 +1 @@
1
- {"version":3,"file":"kit-effect.js","sourceRoot":"","sources":["../../src/internal/kit-effect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,0BAA0B,CAAC;AAmBpD,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,UAA2B,EAC3B,EAAsD,EAC9B,EAAE,CAC1B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;IACvC,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC;AAeL,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,SAA2B,EAC3B,UAAiC,EACZ,EAAE,CACvB,MAAM,CAAC,UAAU,CAAC;IAChB,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,SAAS;CACf,CAAC,CAAC;AAKL,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAc,EACd,OAA2C,EACjC,EAAE;IACZ,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,IAAI,QAAQ,CAAC;QAClB,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,GAAG,OAAO,CAAC,SAAS,YAAY,OAAO,EAAE;QAClD,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import type { Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { Effect } from \"effect\";\nimport { RpcError } from \"@/src/core/errors/rpc.js\";\nimport type { RpcServiceShape } from \"@/src/rpc/service.js\";\n\n/**\n * Get the RPC client and run an operation with it.\n *\n * Reduces boilerplate by combining client retrieval with Effect operations.\n *\n * @example\n * ```typescript\n * yield* withRpc(\n * rpcService,\n * (rpc) => Effect.tryPromise({\n * try: () => rpc.getBalance(address).send(),\n * catch: (e) => new RpcError({ cause: e, message: \"Failed\", url: \"\" })\n * })\n * );\n * ```\n */\nexport const withRpc = <A, E, R>(\n rpcService: RpcServiceShape,\n fn: (rpc: Rpc<SolanaRpcApi>) => Effect.Effect<A, E, R>\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n const rpc = yield* rpcService.getRpc();\n return yield* fn(rpc);\n });\n\n/**\n * Convert a Solana Kit Promise operation to an Effect with custom error classification.\n *\n * Reduces boilerplate when wrapping @solana/kit methods that return promises.\n *\n * @example\n * ```typescript\n * yield* kitTryPromise(\n * () => rpc.getBalance(address).send(),\n * (cause) => new RpcError({ cause, message: \"Failed to get balance\", url })\n * );\n * ```\n */\nexport const kitTryPromise = <A, E>(\n operation: () => Promise<A>,\n classifier: (error: unknown) => E\n): Effect.Effect<A, E> =>\n Effect.tryPromise({\n catch: classifier,\n try: operation,\n });\n\n/**\n * Classify Solana errors into appropriate error types.\n */\nexport const classifyRpcError = (\n error: unknown,\n context: { url: string; operation: string }\n): RpcError => {\n const message = error instanceof Error ? error.message : String(error);\n return new RpcError({\n cause: error,\n message: `${context.operation} failed: ${message}`,\n url: context.url,\n });\n};\n"]}
1
+ {"version":3,"file":"kit-effect.js","sourceRoot":"","sources":["../../src/internal/kit-effect.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,QAAQ,EAAE,MAAM,yBAAyB,CAAC;AAmBnD,MAAM,CAAC,MAAM,OAAO,GAAG,CACrB,UAA2B,EAC3B,EAAsD,EAC9B,EAAE,CAC1B,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,UAAU,CAAC,MAAM,EAAE,CAAC;IACvC,OAAO,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC;AACxB,CAAC,CAAC,CAAC;AAeL,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,SAA2B,EAC3B,UAAiC,EACZ,EAAE,CACvB,MAAM,CAAC,UAAU,CAAC;IAChB,KAAK,EAAE,UAAU;IACjB,GAAG,EAAE,SAAS;CACf,CAAC,CAAC;AAKL,MAAM,CAAC,MAAM,gBAAgB,GAAG,CAC9B,KAAc,EACd,OAA2C,EACjC,EAAE;IACZ,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,OAAO,IAAI,QAAQ,CAAC;QAClB,KAAK,EAAE,KAAK;QACZ,OAAO,EAAE,GAAG,OAAO,CAAC,SAAS,YAAY,OAAO,EAAE;QAClD,GAAG,EAAE,OAAO,CAAC,GAAG;KACjB,CAAC,CAAC;AACL,CAAC,CAAC","sourcesContent":["import type { Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport { Effect } from \"effect\";\nimport { RpcError } from \"#src/core/errors/rpc.js\";\nimport type { RpcServiceShape } from \"#src/rpc/service.js\";\n\n/**\n * Get the RPC client and run an operation with it.\n *\n * Reduces boilerplate by combining client retrieval with Effect operations.\n *\n * @example\n * ```typescript\n * yield* withRpc(\n * rpcService,\n * (rpc) => Effect.tryPromise({\n * try: () => rpc.getBalance(address).send(),\n * catch: (e) => new RpcError({ cause: e, message: \"Failed\", url: \"\" })\n * })\n * );\n * ```\n */\nexport const withRpc = <A, E, R>(\n rpcService: RpcServiceShape,\n fn: (rpc: Rpc<SolanaRpcApi>) => Effect.Effect<A, E, R>\n): Effect.Effect<A, E, R> =>\n Effect.gen(function* () {\n const rpc = yield* rpcService.getRpc();\n return yield* fn(rpc);\n });\n\n/**\n * Convert a Solana Kit Promise operation to an Effect with custom error classification.\n *\n * Reduces boilerplate when wrapping @solana/kit methods that return promises.\n *\n * @example\n * ```typescript\n * yield* kitTryPromise(\n * () => rpc.getBalance(address).send(),\n * (cause) => new RpcError({ cause, message: \"Failed to get balance\", url })\n * );\n * ```\n */\nexport const kitTryPromise = <A, E>(\n operation: () => Promise<A>,\n classifier: (error: unknown) => E\n): Effect.Effect<A, E> =>\n Effect.tryPromise({\n catch: classifier,\n try: operation,\n });\n\n/**\n * Classify Solana errors into appropriate error types.\n */\nexport const classifyRpcError = (\n error: unknown,\n context: { url: string; operation: string }\n): RpcError => {\n const message = error instanceof Error ? error.message : String(error);\n return new RpcError({\n cause: error,\n message: `${context.operation} failed: ${message}`,\n url: context.url,\n });\n};\n"]}
@@ -1,6 +1,6 @@
1
1
  import { getAddressEncoder, getProgramDerivedAddress } from "@solana/addresses";
2
2
  import { Context, Effect, Layer } from "effect";
3
- import { SpanNames } from "../telemetry/index.js";
3
+ import { SpanNames } from "#src/telemetry/index.js";
4
4
  import { PdaDerivationError } from "./types.js";
5
5
  export class PdaService extends Context.Tag("esolana/PdaService")() {
6
6
  }
@@ -1 +1 @@
1
- {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/pda/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,0BAA0B,CAAC;AACrD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAkChD,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAA+B;CAAG;AAKnG,MAAM,WAAW,GAAG,CAAC,IAAa,EAAc,EAAE;IAChD,IAAI,IAAI,YAAY,UAAU,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAErC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,GAAoB,EAAE;IACxC,MAAM,OAAO,GAAoB;QAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,CAChC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;gBAC9B,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,kBAAkB,CAAC;oBACrB,KAAK;oBACL,OAAO,EAAE,oCAAoC,cAAc,EAAE;oBAC7D,cAAc;iBACf,CAAC;gBACJ,GAAG,EAAE,GAAG,EAAE,CACR,wBAAwB,CAAC;oBACvB,cAAc;oBACd,KAAK,EAAE,SAAS;iBACjB,CAAC;aACL,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE;YACpC,UAAU,EAAE;gBACV,cAAc;gBACd,SAAS,EAAE,KAAK,CAAC,MAAM;aACxB;SACF,CAAC,CACH;QAEH,aAAa,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,CACvC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,IAAI,CACxC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAClC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,kBAAkB,EAAE,EAAE,UAAU,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAClF;QAEH,UAAU,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,CACpC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,IAAI,CACxC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAC9B,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAC/E;KACJ,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC","sourcesContent":["import type { Address, ProgramDerivedAddressBump } from \"@solana/addresses\";\nimport { getAddressEncoder, getProgramDerivedAddress } from \"@solana/addresses\";\nimport { Context, Effect, Layer } from \"effect\";\nimport { SpanNames } from \"@/src/telemetry/index.js\";\nimport { PdaDerivationError } from \"./types.js\";\n\nexport type PdaSeed = Uint8Array | Address;\n\nexport type ProgramDerivedAddress = readonly [Address, ProgramDerivedAddressBump];\n\nexport type PdaServiceShape = {\n /**\n * Derive a Program Derived Address from seeds and a program address.\n *\n * @returns A tuple of [address, bumpSeed]\n */\n readonly derive: (\n seeds: readonly PdaSeed[],\n programAddress: Address\n ) => Effect.Effect<ProgramDerivedAddress, PdaDerivationError>;\n\n /**\n * Derive a PDA and return only the address (without bump).\n */\n readonly deriveAddress: (\n seeds: readonly PdaSeed[],\n programAddress: Address\n ) => Effect.Effect<Address, PdaDerivationError>;\n\n /**\n * Derive a PDA and return only the bump seed.\n */\n readonly deriveBump: (\n seeds: readonly PdaSeed[],\n programAddress: Address\n ) => Effect.Effect<ProgramDerivedAddressBump, PdaDerivationError>;\n};\n\nexport class PdaService extends Context.Tag(\"esolana/PdaService\")<PdaService, PdaServiceShape>() {}\n\n/**\n * Convert seed to Uint8Array format required by @solana/addresses.\n */\nconst toSeedBytes = (seed: PdaSeed): Uint8Array => {\n if (seed instanceof Uint8Array) {\n return seed;\n }\n // Address type - use address encoder\n const encoder = getAddressEncoder();\n const encoded = encoder.encode(seed);\n // Convert ReadonlyUint8Array to Uint8Array\n return new Uint8Array(encoded);\n};\n\nconst makeService = (): PdaServiceShape => {\n const service: PdaServiceShape = {\n derive: (seeds, programAddress) =>\n Effect.gen(function* () {\n const seedBytes = seeds.map(toSeedBytes);\n return yield* Effect.tryPromise({\n catch: (cause) =>\n new PdaDerivationError({\n cause,\n message: `Failed to derive PDA for program ${programAddress}`,\n programAddress,\n }),\n try: () =>\n getProgramDerivedAddress({\n programAddress,\n seeds: seedBytes,\n }),\n });\n }).pipe(\n Effect.withSpan(SpanNames.PDA_DERIVE, {\n attributes: {\n programAddress,\n seedCount: seeds.length,\n },\n })\n ),\n\n deriveAddress: (seeds, programAddress) =>\n service.derive(seeds, programAddress).pipe(\n Effect.map(([address]) => address),\n Effect.withSpan(SpanNames.PDA_DERIVE_ADDRESS, { attributes: { programAddress } })\n ),\n\n deriveBump: (seeds, programAddress) =>\n service.derive(seeds, programAddress).pipe(\n Effect.map(([, bump]) => bump),\n Effect.withSpan(SpanNames.PDA_DERIVE_BUMP, { attributes: { programAddress } })\n ),\n };\n\n return service;\n};\n\nexport const PdaServiceLive = Layer.succeed(PdaService, PdaService.of(makeService()));\n"]}
1
+ {"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/pda/service.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,iBAAiB,EAAE,wBAAwB,EAAE,MAAM,mBAAmB,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,yBAAyB,CAAC;AACpD,OAAO,EAAE,kBAAkB,EAAE,MAAM,YAAY,CAAC;AAkChD,MAAM,OAAO,UAAW,SAAQ,OAAO,CAAC,GAAG,CAAC,oBAAoB,CAAC,EAA+B;CAAG;AAKnG,MAAM,WAAW,GAAG,CAAC,IAAa,EAAc,EAAE;IAChD,IAAI,IAAI,YAAY,UAAU,EAAE,CAAC;QAC/B,OAAO,IAAI,CAAC;IACd,CAAC;IAED,MAAM,OAAO,GAAG,iBAAiB,EAAE,CAAC;IACpC,MAAM,OAAO,GAAG,OAAO,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;IAErC,OAAO,IAAI,UAAU,CAAC,OAAO,CAAC,CAAC;AACjC,CAAC,CAAC;AAEF,MAAM,WAAW,GAAG,GAAoB,EAAE;IACxC,MAAM,OAAO,GAAoB;QAC/B,MAAM,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,CAChC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,SAAS,GAAG,KAAK,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC;YACzC,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC;gBAC9B,KAAK,EAAE,CAAC,KAAK,EAAE,EAAE,CACf,IAAI,kBAAkB,CAAC;oBACrB,KAAK;oBACL,OAAO,EAAE,oCAAoC,cAAc,EAAE;oBAC7D,cAAc;iBACf,CAAC;gBACJ,GAAG,EAAE,GAAG,EAAE,CACR,wBAAwB,CAAC;oBACvB,cAAc;oBACd,KAAK,EAAE,SAAS;iBACjB,CAAC;aACL,CAAC,CAAC;QACL,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,UAAU,EAAE;YACpC,UAAU,EAAE;gBACV,cAAc;gBACd,SAAS,EAAE,KAAK,CAAC,MAAM;aACxB;SACF,CAAC,CACH;QAEH,aAAa,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,CACvC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,IAAI,CACxC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,EAAE,EAAE,CAAC,OAAO,CAAC,EAClC,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,kBAAkB,EAAE,EAAE,UAAU,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAClF;QAEH,UAAU,EAAE,CAAC,KAAK,EAAE,cAAc,EAAE,EAAE,CACpC,OAAO,CAAC,MAAM,CAAC,KAAK,EAAE,cAAc,CAAC,CAAC,IAAI,CACxC,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,IAAI,CAAC,EAAE,EAAE,CAAC,IAAI,CAAC,EAC9B,MAAM,CAAC,QAAQ,CAAC,SAAS,CAAC,eAAe,EAAE,EAAE,UAAU,EAAE,EAAE,cAAc,EAAE,EAAE,CAAC,CAC/E;KACJ,CAAC;IAEF,OAAO,OAAO,CAAC;AACjB,CAAC,CAAC;AAEF,MAAM,CAAC,MAAM,cAAc,GAAG,KAAK,CAAC,OAAO,CAAC,UAAU,EAAE,UAAU,CAAC,EAAE,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC","sourcesContent":["import type { Address, ProgramDerivedAddressBump } from \"@solana/addresses\";\nimport { getAddressEncoder, getProgramDerivedAddress } from \"@solana/addresses\";\nimport { Context, Effect, Layer } from \"effect\";\nimport { SpanNames } from \"#src/telemetry/index.js\";\nimport { PdaDerivationError } from \"./types.js\";\n\nexport type PdaSeed = Uint8Array | Address;\n\nexport type ProgramDerivedAddress = readonly [Address, ProgramDerivedAddressBump];\n\nexport type PdaServiceShape = {\n /**\n * Derive a Program Derived Address from seeds and a program address.\n *\n * @returns A tuple of [address, bumpSeed]\n */\n readonly derive: (\n seeds: readonly PdaSeed[],\n programAddress: Address\n ) => Effect.Effect<ProgramDerivedAddress, PdaDerivationError>;\n\n /**\n * Derive a PDA and return only the address (without bump).\n */\n readonly deriveAddress: (\n seeds: readonly PdaSeed[],\n programAddress: Address\n ) => Effect.Effect<Address, PdaDerivationError>;\n\n /**\n * Derive a PDA and return only the bump seed.\n */\n readonly deriveBump: (\n seeds: readonly PdaSeed[],\n programAddress: Address\n ) => Effect.Effect<ProgramDerivedAddressBump, PdaDerivationError>;\n};\n\nexport class PdaService extends Context.Tag(\"esolana/PdaService\")<PdaService, PdaServiceShape>() {}\n\n/**\n * Convert seed to Uint8Array format required by @solana/addresses.\n */\nconst toSeedBytes = (seed: PdaSeed): Uint8Array => {\n if (seed instanceof Uint8Array) {\n return seed;\n }\n // Address type - use address encoder\n const encoder = getAddressEncoder();\n const encoded = encoder.encode(seed);\n // Convert ReadonlyUint8Array to Uint8Array\n return new Uint8Array(encoded);\n};\n\nconst makeService = (): PdaServiceShape => {\n const service: PdaServiceShape = {\n derive: (seeds, programAddress) =>\n Effect.gen(function* () {\n const seedBytes = seeds.map(toSeedBytes);\n return yield* Effect.tryPromise({\n catch: (cause) =>\n new PdaDerivationError({\n cause,\n message: `Failed to derive PDA for program ${programAddress}`,\n programAddress,\n }),\n try: () =>\n getProgramDerivedAddress({\n programAddress,\n seeds: seedBytes,\n }),\n });\n }).pipe(\n Effect.withSpan(SpanNames.PDA_DERIVE, {\n attributes: {\n programAddress,\n seedCount: seeds.length,\n },\n })\n ),\n\n deriveAddress: (seeds, programAddress) =>\n service.derive(seeds, programAddress).pipe(\n Effect.map(([address]) => address),\n Effect.withSpan(SpanNames.PDA_DERIVE_ADDRESS, { attributes: { programAddress } })\n ),\n\n deriveBump: (seeds, programAddress) =>\n service.derive(seeds, programAddress).pipe(\n Effect.map(([, bump]) => bump),\n Effect.withSpan(SpanNames.PDA_DERIVE_BUMP, { attributes: { programAddress } })\n ),\n };\n\n return service;\n};\n\nexport const PdaServiceLive = Layer.succeed(PdaService, PdaService.of(makeService()));\n"]}
@@ -1,19 +1,19 @@
1
1
  import { Layer } from "effect";
2
- import type { BalanceService } from "../balance/index.js";
3
- import type { PdaService } from "../pda/index.js";
4
- import type { ProgramWriter } from "../program/index.js";
5
- import type { RpcService } from "../rpc/index.js";
6
- import type { SignerService, WalletAdapter } from "../signer/index.js";
7
- import type { TokenService } from "../token/index.js";
8
- import type { TransactionService } from "../tx/index.js";
9
- import type { Cluster } from "../types/index.js";
2
+ import type { BalanceService } from "#src/balance/index.js";
3
+ import type { PdaService } from "#src/pda/index.js";
4
+ import type { ProgramReader, ProgramWriter } from "#src/program/index.js";
5
+ import type { RpcService } from "#src/rpc/index.js";
6
+ import type { SignerService, WalletAdapter } from "#src/signer/index.js";
7
+ import type { TokenService } from "#src/token/index.js";
8
+ import type { TransactionService } from "#src/tx/index.js";
9
+ import type { Cluster } from "#src/types/index.js";
10
10
  export type SolanaClusterConfig = {
11
11
  readonly cluster: Cluster;
12
12
  readonly rpcUrl?: string;
13
13
  readonly wsUrl?: string;
14
14
  };
15
15
  export declare function makeRpcLayer(config: SolanaClusterConfig): Layer.Layer<RpcService>;
16
- export declare const effectSolanaServices: Layer.Layer<BalanceService | PdaService | ProgramWriter | TokenService | TransactionService, never, RpcService | SignerService>;
16
+ export declare const effectSolanaServices: Layer.Layer<BalanceService | PdaService | ProgramReader | ProgramWriter | TokenService | TransactionService, never, RpcService | SignerService>;
17
17
  export declare function makeSignerLayer(getAdapter: () => WalletAdapter): Layer.Layer<SignerService>;
18
- export declare function makeSolanaLayer(config: SolanaClusterConfig, getAdapter: () => WalletAdapter): Layer.Layer<RpcService | SignerService | BalanceService | TokenService | TransactionService | PdaService | ProgramWriter>;
18
+ export declare function makeSolanaLayer(config: SolanaClusterConfig, getAdapter: () => WalletAdapter): Layer.Layer<RpcService | SignerService | BalanceService | TokenService | TransactionService | PdaService | ProgramReader | ProgramWriter>;
19
19
  //# sourceMappingURL=layers.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/presets/layers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAE7D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAC;AAErD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AAEzD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAE5D,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,sBAAsB,CAAC;AAOnE,MAAM,MAAM,mBAAmB,GAAG;IAIhC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAK1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAKzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAyCF,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAWjF;AAsBD,eAAO,MAAM,oBAAoB,iIAMhC,CAAC;AA4BF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAE3F;AAiCD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,MAAM,aAAa,GAC9B,KAAK,CAAC,KAAK,CACV,UAAU,GACV,aAAa,GACb,cAAc,GACd,YAAY,GACZ,kBAAkB,GAClB,UAAU,GACV,aAAa,CAChB,CAOA"}
1
+ {"version":3,"file":"layers.d.ts","sourceRoot":"","sources":["../../src/presets/layers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAC/B,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,uBAAuB,CAAC;AAE5D,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAE1E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAEpD,OAAO,KAAK,EAAE,aAAa,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAEzE,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAExD,OAAO,KAAK,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,KAAK,EAAE,OAAO,EAAiB,MAAM,qBAAqB,CAAC;AAOlE,MAAM,MAAM,mBAAmB,GAAG;IAIhC,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAC;IAK1B,QAAQ,CAAC,MAAM,CAAC,EAAE,MAAM,CAAC;IAKzB,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAyCF,wBAAgB,YAAY,CAAC,MAAM,EAAE,mBAAmB,GAAG,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAWjF;AAsBD,eAAO,MAAM,oBAAoB,iJAOhC,CAAC;AA4BF,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,aAAa,GAAG,KAAK,CAAC,KAAK,CAAC,aAAa,CAAC,CAE3F;AAiCD,wBAAgB,eAAe,CAC7B,MAAM,EAAE,mBAAmB,EAC3B,UAAU,EAAE,MAAM,aAAa,GAC9B,KAAK,CAAC,KAAK,CACV,UAAU,GACV,aAAa,GACb,cAAc,GACd,YAAY,GACZ,kBAAkB,GAClB,UAAU,GACV,aAAa,GACb,aAAa,CAChB,CAOA"}
@@ -1,11 +1,11 @@
1
1
  import { Layer } from "effect";
2
- import { BalanceServiceLive } from "../balance/index.js";
3
- import { PdaServiceLive } from "../pda/index.js";
4
- import { ProgramWriterLive } from "../program/index.js";
5
- import { makeRpcServiceLive } from "../rpc/index.js";
6
- import { makeSignerServiceFromAdapter } from "../signer/index.js";
7
- import { TokenServiceLive } from "../token/index.js";
8
- import { TransactionServiceLive } from "../tx/index.js";
2
+ import { BalanceServiceLive } from "#src/balance/index.js";
3
+ import { PdaServiceLive } from "#src/pda/index.js";
4
+ import { ProgramReaderLive, ProgramWriterLive } from "#src/program/index.js";
5
+ import { makeRpcServiceLive } from "#src/rpc/index.js";
6
+ import { makeSignerServiceFromAdapter } from "#src/signer/index.js";
7
+ import { TokenServiceLive } from "#src/token/index.js";
8
+ import { TransactionServiceLive } from "#src/tx/index.js";
9
9
  const DEFAULT_RPC_URLS = {
10
10
  devnet: "https://api.devnet.solana.com",
11
11
  localnet: "http://127.0.0.1:8899",
@@ -28,7 +28,7 @@ export function makeRpcLayer(config) {
28
28
  };
29
29
  return makeRpcServiceLive(clusterConfig);
30
30
  }
31
- export const effectSolanaServices = Layer.mergeAll(BalanceServiceLive, TokenServiceLive, TransactionServiceLive, PdaServiceLive, ProgramWriterLive);
31
+ export const effectSolanaServices = Layer.mergeAll(BalanceServiceLive, TokenServiceLive, TransactionServiceLive, PdaServiceLive, ProgramReaderLive, ProgramWriterLive);
32
32
  export function makeSignerLayer(getAdapter) {
33
33
  return makeSignerServiceFromAdapter(getAdapter);
34
34
  }
@@ -1 +1 @@
1
- {"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/presets/layers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAC;AAE5D,OAAO,EAAE,cAAc,EAAE,MAAM,oBAAoB,CAAC;AAEpD,OAAO,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAE3D,OAAO,EAAE,kBAAkB,EAAE,MAAM,oBAAoB,CAAC;AAExD,OAAO,EAAE,4BAA4B,EAAE,MAAM,uBAAuB,CAAC;AAErE,OAAO,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;AAExD,OAAO,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AA4B3D,MAAM,gBAAgB,GAA4B;IAChD,MAAM,EAAE,+BAA+B;IACvC,QAAQ,EAAE,uBAAuB;IACjC,cAAc,EAAE,qCAAqC;IACrD,OAAO,EAAE,gCAAgC;CAC1C,CAAC;AAKF,MAAM,eAAe,GAAwC;IAC3D,MAAM,EAAE,6BAA6B;IACrC,QAAQ,EAAE,qBAAqB;IAC/B,cAAc,EAAE,mCAAmC;IACnD,OAAO,EAAE,8BAA8B;CACxC,CAAC;AAqBF,MAAM,UAAU,YAAY,CAAC,MAA2B;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE9D,MAAM,aAAa,GAAkB;QACnC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM;QACN,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5B,CAAC;IAEF,OAAO,kBAAkB,CAAC,aAAa,CAAC,CAAC;AAC3C,CAAC;AAsBD,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,QAAQ,CAChD,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,CAClB,CAAC;AA4BF,MAAM,UAAU,eAAe,CAAC,UAA+B;IAC7D,OAAO,4BAA4B,CAAC,UAAU,CAAC,CAAC;AAClD,CAAC;AAiCD,MAAM,UAAU,eAAe,CAC7B,MAA2B,EAC3B,UAA+B;IAU/B,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEzD,OAAO,KAAK,CAAC,YAAY,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import { Layer } from \"effect\";\nimport type { BalanceService } from \"@/src/balance/index.js\";\nimport { BalanceServiceLive } from \"@/src/balance/index.js\";\nimport type { PdaService } from \"@/src/pda/index.js\";\nimport { PdaServiceLive } from \"@/src/pda/index.js\";\nimport type { ProgramWriter } from \"@/src/program/index.js\";\nimport { ProgramWriterLive } from \"@/src/program/index.js\";\nimport type { RpcService } from \"@/src/rpc/index.js\";\nimport { makeRpcServiceLive } from \"@/src/rpc/index.js\";\nimport type { SignerService, WalletAdapter } from \"@/src/signer/index.js\";\nimport { makeSignerServiceFromAdapter } from \"@/src/signer/index.js\";\nimport type { TokenService } from \"@/src/token/index.js\";\nimport { TokenServiceLive } from \"@/src/token/index.js\";\nimport type { TransactionService } from \"@/src/tx/index.js\";\nimport { TransactionServiceLive } from \"@/src/tx/index.js\";\nimport type { Cluster, ClusterConfig } from \"@/src/types/index.js\";\n\n/**\n * Configuration for connecting to a Solana cluster.\n *\n * @category Configuration\n */\nexport type SolanaClusterConfig = {\n /**\n * The cluster environment (mainnet-beta, devnet, testnet, localnet).\n */\n readonly cluster: Cluster;\n\n /**\n * Override the default RPC URL for the cluster.\n */\n readonly rpcUrl?: string;\n\n /**\n * Optional WebSocket URL for subscriptions.\n */\n readonly wsUrl?: string;\n};\n\n/**\n * Default RPC endpoints for Solana clusters.\n */\nconst DEFAULT_RPC_URLS: Record<Cluster, string> = {\n devnet: \"https://api.devnet.solana.com\",\n localnet: \"http://127.0.0.1:8899\",\n \"mainnet-beta\": \"https://api.mainnet-beta.solana.com\",\n testnet: \"https://api.testnet.solana.com\",\n};\n\n/**\n * Default WebSocket endpoints for Solana clusters.\n */\nconst DEFAULT_WS_URLS: Record<Cluster, string | undefined> = {\n devnet: \"wss://api.devnet.solana.com\",\n localnet: \"ws://127.0.0.1:8900\",\n \"mainnet-beta\": \"wss://api.mainnet-beta.solana.com\",\n testnet: \"wss://api.testnet.solana.com\",\n};\n\n/**\n * Create an RpcService layer from cluster configuration.\n *\n * @param config - Cluster configuration\n * @returns A Layer providing RpcService\n *\n * @category Layers\n *\n * @example\n * ```typescript\n * const rpcLayer = makeRpcLayer({ cluster: \"devnet\" });\n *\n * // Override default RPC URL\n * const customRpcLayer = makeRpcLayer({\n * cluster: \"mainnet-beta\",\n * rpcUrl: \"https://my-custom-rpc.com\",\n * });\n * ```\n */\nexport function makeRpcLayer(config: SolanaClusterConfig): Layer.Layer<RpcService> {\n const rpcUrl = config.rpcUrl ?? DEFAULT_RPC_URLS[config.cluster];\n const wsUrl = config.wsUrl ?? DEFAULT_WS_URLS[config.cluster];\n\n const clusterConfig: ClusterConfig = {\n cluster: config.cluster,\n rpcUrl,\n ...(wsUrl ? { wsUrl } : {}),\n };\n\n return makeRpcServiceLive(clusterConfig);\n}\n\n/**\n * Compose all application services (Balance, Token, Transaction, PDA, ProgramWriter).\n * Requires RpcService and SignerService to be provided.\n *\n * @category Layers\n *\n * @example\n * ```typescript\n * import { Layer } from \"effect\";\n * import { makeRpcLayer, makeSignerLayer, effectSolanaServices } from \"@prb/effect-solana\";\n *\n * const rpcLayer = makeRpcLayer({ cluster: \"devnet\" });\n * const signerLayer = makeSignerLayer(walletAdapter);\n *\n * const appLayer = Layer.provideMerge(\n * effectSolanaServices,\n * Layer.mergeAll(rpcLayer, signerLayer)\n * );\n * ```\n */\nexport const effectSolanaServices = Layer.mergeAll(\n BalanceServiceLive,\n TokenServiceLive,\n TransactionServiceLive,\n PdaServiceLive,\n ProgramWriterLive\n);\n\n/**\n * Create a SignerService layer from a wallet adapter.\n *\n * @param getAdapter - Function that returns the current wallet adapter\n * @returns A Layer providing SignerService\n *\n * @category Layers\n *\n * @example\n * ```typescript\n * import { useWallet } from \"@solana/wallet-adapter-react\";\n *\n * function App() {\n * const wallet = useWallet();\n *\n * const signerLayer = makeSignerLayer(() => ({\n * publicKey: wallet.publicKey,\n * connected: wallet.connected,\n * signTransaction: wallet.signTransaction!,\n * signAllTransactions: wallet.signAllTransactions!,\n * }));\n *\n * // Use signerLayer in your runtime...\n * }\n * ```\n */\nexport function makeSignerLayer(getAdapter: () => WalletAdapter): Layer.Layer<SignerService> {\n return makeSignerServiceFromAdapter(getAdapter);\n}\n\n/**\n * Create a complete Solana layer with all services.\n *\n * @param config - Cluster configuration\n * @param getAdapter - Function that returns the current wallet adapter\n * @returns A Layer providing all Solana services\n *\n * @category Layers\n *\n * @example\n * ```typescript\n * import { makeSolanaLayer } from \"@prb/effect-solana\";\n * import { useWallet } from \"@solana/wallet-adapter-react\";\n *\n * function App() {\n * const wallet = useWallet();\n *\n * const solanaLayer = makeSolanaLayer(\n * { cluster: \"devnet\" },\n * () => ({\n * publicKey: wallet.publicKey,\n * connected: wallet.connected,\n * signTransaction: wallet.signTransaction!,\n * signAllTransactions: wallet.signAllTransactions!,\n * })\n * );\n *\n * // Use solanaLayer in your Effect runtime...\n * }\n * ```\n */\nexport function makeSolanaLayer(\n config: SolanaClusterConfig,\n getAdapter: () => WalletAdapter\n): Layer.Layer<\n | RpcService\n | SignerService\n | BalanceService\n | TokenService\n | TransactionService\n | PdaService\n | ProgramWriter\n> {\n const rpcLayer = makeRpcLayer(config);\n const signerLayer = makeSignerLayer(getAdapter);\n\n const baseLayers = Layer.mergeAll(rpcLayer, signerLayer);\n\n return Layer.provideMerge(effectSolanaServices, baseLayers);\n}\n"]}
1
+ {"version":3,"file":"layers.js","sourceRoot":"","sources":["../../src/presets/layers.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAC;AAE/B,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,mBAAmB,CAAC;AAEnD,OAAO,EAAE,iBAAiB,EAAE,iBAAiB,EAAE,MAAM,uBAAuB,CAAC;AAE7E,OAAO,EAAE,kBAAkB,EAAE,MAAM,mBAAmB,CAAC;AAEvD,OAAO,EAAE,4BAA4B,EAAE,MAAM,sBAAsB,CAAC;AAEpE,OAAO,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAEvD,OAAO,EAAE,sBAAsB,EAAE,MAAM,kBAAkB,CAAC;AA4B1D,MAAM,gBAAgB,GAA4B;IAChD,MAAM,EAAE,+BAA+B;IACvC,QAAQ,EAAE,uBAAuB;IACjC,cAAc,EAAE,qCAAqC;IACrD,OAAO,EAAE,gCAAgC;CAC1C,CAAC;AAKF,MAAM,eAAe,GAAwC;IAC3D,MAAM,EAAE,6BAA6B;IACrC,QAAQ,EAAE,qBAAqB;IAC/B,cAAc,EAAE,mCAAmC;IACnD,OAAO,EAAE,8BAA8B;CACxC,CAAC;AAqBF,MAAM,UAAU,YAAY,CAAC,MAA2B;IACtD,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,IAAI,gBAAgB,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IACjE,MAAM,KAAK,GAAG,MAAM,CAAC,KAAK,IAAI,eAAe,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC;IAE9D,MAAM,aAAa,GAAkB;QACnC,OAAO,EAAE,MAAM,CAAC,OAAO;QACvB,MAAM;QACN,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC;KAC5B,CAAC;IAEF,OAAO,kBAAkB,CAAC,aAAa,CAAC,CAAC;AAC3C,CAAC;AAsBD,MAAM,CAAC,MAAM,oBAAoB,GAAG,KAAK,CAAC,QAAQ,CAChD,kBAAkB,EAClB,gBAAgB,EAChB,sBAAsB,EACtB,cAAc,EACd,iBAAiB,EACjB,iBAAiB,CAClB,CAAC;AA4BF,MAAM,UAAU,eAAe,CAAC,UAA+B;IAC7D,OAAO,4BAA4B,CAAC,UAAU,CAAC,CAAC;AAClD,CAAC;AAiCD,MAAM,UAAU,eAAe,CAC7B,MAA2B,EAC3B,UAA+B;IAW/B,MAAM,QAAQ,GAAG,YAAY,CAAC,MAAM,CAAC,CAAC;IACtC,MAAM,WAAW,GAAG,eAAe,CAAC,UAAU,CAAC,CAAC;IAEhD,MAAM,UAAU,GAAG,KAAK,CAAC,QAAQ,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;IAEzD,OAAO,KAAK,CAAC,YAAY,CAAC,oBAAoB,EAAE,UAAU,CAAC,CAAC;AAC9D,CAAC","sourcesContent":["import { Layer } from \"effect\";\nimport type { BalanceService } from \"#src/balance/index.js\";\nimport { BalanceServiceLive } from \"#src/balance/index.js\";\nimport type { PdaService } from \"#src/pda/index.js\";\nimport { PdaServiceLive } from \"#src/pda/index.js\";\nimport type { ProgramReader, ProgramWriter } from \"#src/program/index.js\";\nimport { ProgramReaderLive, ProgramWriterLive } from \"#src/program/index.js\";\nimport type { RpcService } from \"#src/rpc/index.js\";\nimport { makeRpcServiceLive } from \"#src/rpc/index.js\";\nimport type { SignerService, WalletAdapter } from \"#src/signer/index.js\";\nimport { makeSignerServiceFromAdapter } from \"#src/signer/index.js\";\nimport type { TokenService } from \"#src/token/index.js\";\nimport { TokenServiceLive } from \"#src/token/index.js\";\nimport type { TransactionService } from \"#src/tx/index.js\";\nimport { TransactionServiceLive } from \"#src/tx/index.js\";\nimport type { Cluster, ClusterConfig } from \"#src/types/index.js\";\n\n/**\n * Configuration for connecting to a Solana cluster.\n *\n * @category Configuration\n */\nexport type SolanaClusterConfig = {\n /**\n * The cluster environment (mainnet-beta, devnet, testnet, localnet).\n */\n readonly cluster: Cluster;\n\n /**\n * Override the default RPC URL for the cluster.\n */\n readonly rpcUrl?: string;\n\n /**\n * Optional WebSocket URL for subscriptions.\n */\n readonly wsUrl?: string;\n};\n\n/**\n * Default RPC endpoints for Solana clusters.\n */\nconst DEFAULT_RPC_URLS: Record<Cluster, string> = {\n devnet: \"https://api.devnet.solana.com\",\n localnet: \"http://127.0.0.1:8899\",\n \"mainnet-beta\": \"https://api.mainnet-beta.solana.com\",\n testnet: \"https://api.testnet.solana.com\",\n};\n\n/**\n * Default WebSocket endpoints for Solana clusters.\n */\nconst DEFAULT_WS_URLS: Record<Cluster, string | undefined> = {\n devnet: \"wss://api.devnet.solana.com\",\n localnet: \"ws://127.0.0.1:8900\",\n \"mainnet-beta\": \"wss://api.mainnet-beta.solana.com\",\n testnet: \"wss://api.testnet.solana.com\",\n};\n\n/**\n * Create an RpcService layer from cluster configuration.\n *\n * @param config - Cluster configuration\n * @returns A Layer providing RpcService\n *\n * @category Layers\n *\n * @example\n * ```typescript\n * const rpcLayer = makeRpcLayer({ cluster: \"devnet\" });\n *\n * // Override default RPC URL\n * const customRpcLayer = makeRpcLayer({\n * cluster: \"mainnet-beta\",\n * rpcUrl: \"https://my-custom-rpc.com\",\n * });\n * ```\n */\nexport function makeRpcLayer(config: SolanaClusterConfig): Layer.Layer<RpcService> {\n const rpcUrl = config.rpcUrl ?? DEFAULT_RPC_URLS[config.cluster];\n const wsUrl = config.wsUrl ?? DEFAULT_WS_URLS[config.cluster];\n\n const clusterConfig: ClusterConfig = {\n cluster: config.cluster,\n rpcUrl,\n ...(wsUrl ? { wsUrl } : {}),\n };\n\n return makeRpcServiceLive(clusterConfig);\n}\n\n/**\n * Compose all application services (Balance, Token, Transaction, PDA, ProgramReader, ProgramWriter).\n * Requires RpcService and SignerService to be provided.\n *\n * @category Layers\n *\n * @example\n * ```typescript\n * import { Layer } from \"effect\";\n * import { makeRpcLayer, makeSignerLayer, effectSolanaServices } from \"@prb/effect-solana\";\n *\n * const rpcLayer = makeRpcLayer({ cluster: \"devnet\" });\n * const signerLayer = makeSignerLayer(walletAdapter);\n *\n * const appLayer = Layer.provideMerge(\n * effectSolanaServices,\n * Layer.mergeAll(rpcLayer, signerLayer)\n * );\n * ```\n */\nexport const effectSolanaServices = Layer.mergeAll(\n BalanceServiceLive,\n TokenServiceLive,\n TransactionServiceLive,\n PdaServiceLive,\n ProgramReaderLive,\n ProgramWriterLive\n);\n\n/**\n * Create a SignerService layer from a wallet adapter.\n *\n * @param getAdapter - Function that returns the current wallet adapter\n * @returns A Layer providing SignerService\n *\n * @category Layers\n *\n * @example\n * ```typescript\n * import { useWallet } from \"@solana/wallet-adapter-react\";\n *\n * function App() {\n * const wallet = useWallet();\n *\n * const signerLayer = makeSignerLayer(() => ({\n * publicKey: wallet.publicKey,\n * connected: wallet.connected,\n * signTransaction: wallet.signTransaction!,\n * signAllTransactions: wallet.signAllTransactions!,\n * }));\n *\n * // Use signerLayer in your runtime...\n * }\n * ```\n */\nexport function makeSignerLayer(getAdapter: () => WalletAdapter): Layer.Layer<SignerService> {\n return makeSignerServiceFromAdapter(getAdapter);\n}\n\n/**\n * Create a complete Solana layer with all services.\n *\n * @param config - Cluster configuration\n * @param getAdapter - Function that returns the current wallet adapter\n * @returns A Layer providing all Solana services\n *\n * @category Layers\n *\n * @example\n * ```typescript\n * import { makeSolanaLayer } from \"@prb/effect-solana\";\n * import { useWallet } from \"@solana/wallet-adapter-react\";\n *\n * function App() {\n * const wallet = useWallet();\n *\n * const solanaLayer = makeSolanaLayer(\n * { cluster: \"devnet\" },\n * () => ({\n * publicKey: wallet.publicKey,\n * connected: wallet.connected,\n * signTransaction: wallet.signTransaction!,\n * signAllTransactions: wallet.signAllTransactions!,\n * })\n * );\n *\n * // Use solanaLayer in your Effect runtime...\n * }\n * ```\n */\nexport function makeSolanaLayer(\n config: SolanaClusterConfig,\n getAdapter: () => WalletAdapter\n): Layer.Layer<\n | RpcService\n | SignerService\n | BalanceService\n | TokenService\n | TransactionService\n | PdaService\n | ProgramReader\n | ProgramWriter\n> {\n const rpcLayer = makeRpcLayer(config);\n const signerLayer = makeSignerLayer(getAdapter);\n\n const baseLayers = Layer.mergeAll(rpcLayer, signerLayer);\n\n return Layer.provideMerge(effectSolanaServices, baseLayers);\n}\n"]}
@@ -1,3 +1,4 @@
1
+ export * from "./reader.js";
1
2
  export * from "./service.js";
2
3
  export * from "./types.js";
3
4
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/program/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/program/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC"}
@@ -1,3 +1,4 @@
1
+ export * from "./reader.js";
1
2
  export * from "./service.js";
2
3
  export * from "./types.js";
3
4
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/program/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC","sourcesContent":["export * from \"./service.js\";\nexport * from \"./types.js\";\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/program/index.ts"],"names":[],"mappings":"AAAA,cAAc,aAAa,CAAC;AAC5B,cAAc,cAAc,CAAC;AAC7B,cAAc,YAAY,CAAC","sourcesContent":["export * from \"./reader.js\";\nexport * from \"./service.js\";\nexport * from \"./types.js\";\n"]}
@@ -0,0 +1,20 @@
1
+ import type { Address } from "@solana/addresses";
2
+ import type { Rpc, SolanaRpcApi } from "@solana/kit";
3
+ import type { AccountInfo } from "@solana/web3.js";
4
+ import { PublicKey } from "@solana/web3.js";
5
+ import { Buffer } from "buffer";
6
+ import type { AccountsMap } from "../types.js";
7
+ export declare function toPublicKey(address: Address | string): PublicKey;
8
+ export declare function toAnchorAccounts(accounts: AccountsMap): Record<string, PublicKey>;
9
+ export declare function toAnchorArgs(args: readonly unknown[]): unknown[];
10
+ export type Base64AccountInfoLike = Readonly<{
11
+ data: readonly [string, string];
12
+ executable: boolean;
13
+ lamports: bigint | number;
14
+ owner: Address;
15
+ rentEpoch?: bigint | number;
16
+ }>;
17
+ export declare function decodeBase64ToBuffer(encoded: string): Buffer;
18
+ export declare function toWeb3AccountInfo(value: Base64AccountInfoLike): AccountInfo<Buffer>;
19
+ export declare function makeProgramConnectionShim(rpc: Rpc<SolanaRpcApi>, serviceName: "ProgramReader" | "ProgramWriter"): Program["provider"]["connection"];
20
+ //# sourceMappingURL=anchor-helpers.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor-helpers.d.ts","sourceRoot":"","sources":["../../../src/program/internal/anchor-helpers.ts"],"names":[],"mappings":"AAUA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AACrD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AACnD,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,aAAa,CAAC;AAK/C,wBAAgB,WAAW,CAAC,OAAO,EAAE,OAAO,GAAG,MAAM,GAAG,SAAS,CAEhE;AAKD,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,WAAW,GAAG,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,CAMjF;AAMD,wBAAgB,YAAY,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,EAAE,CAUhE;AAED,MAAM,MAAM,qBAAqB,GAAG,QAAQ,CAAC;IAC3C,IAAI,EAAE,SAAS,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAChC,UAAU,EAAE,OAAO,CAAC;IACpB,QAAQ,EAAE,MAAM,GAAG,MAAM,CAAC;IAC1B,KAAK,EAAE,OAAO,CAAC;IACf,SAAS,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CAC7B,CAAC,CAAC;AAEH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAE5D;AAED,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,qBAAqB,GAAG,WAAW,CAAC,MAAM,CAAC,CAYnF;AAED,wBAAgB,yBAAyB,CACvC,GAAG,EAAE,GAAG,CAAC,YAAY,CAAC,EACtB,WAAW,EAAE,eAAe,GAAG,eAAe,GAC7C,OAAO,CAAC,UAAU,CAAC,CAAC,YAAY,CAAC,CA6BnC"}
@@ -0,0 +1,64 @@
1
+ import { PublicKey } from "@solana/web3.js";
2
+ import BN from "bn.js";
3
+ import { Buffer } from "buffer";
4
+ export function toPublicKey(address) {
5
+ return new PublicKey(address);
6
+ }
7
+ export function toAnchorAccounts(accounts) {
8
+ const result = {};
9
+ for (const [key, value] of Object.entries(accounts)) {
10
+ result[key] = toPublicKey(value);
11
+ }
12
+ return result;
13
+ }
14
+ export function toAnchorArgs(args) {
15
+ return args.map((arg) => {
16
+ if (typeof arg === "bigint") {
17
+ return new BN(arg.toString());
18
+ }
19
+ if (typeof arg === "number" && Number.isInteger(arg)) {
20
+ return new BN(arg.toString());
21
+ }
22
+ return arg;
23
+ });
24
+ }
25
+ export function decodeBase64ToBuffer(encoded) {
26
+ return Buffer.from(encoded, "base64");
27
+ }
28
+ export function toWeb3AccountInfo(value) {
29
+ const [encodedData] = value.data;
30
+ return {
31
+ data: decodeBase64ToBuffer(encodedData),
32
+ executable: value.executable,
33
+ lamports: Number(value.lamports),
34
+ owner: toPublicKey(value.owner),
35
+ rentEpoch: Number(value.rentEpoch ?? 0),
36
+ };
37
+ }
38
+ export function makeProgramConnectionShim(rpc, serviceName) {
39
+ const knownConnectionMethods = {
40
+ getAccountInfo: async (pubkey) => {
41
+ const response = await rpc
42
+ .getAccountInfo(pubkey.toBase58(), { encoding: "base64" })
43
+ .send();
44
+ return response.value === null
45
+ ? null
46
+ : toWeb3AccountInfo(response.value);
47
+ },
48
+ getLatestBlockhash: async () => {
49
+ const { blockhash, lastValidBlockHeight } = (await rpc.getLatestBlockhash().send()).value;
50
+ return { blockhash, lastValidBlockHeight: Number(lastValidBlockHeight) };
51
+ },
52
+ };
53
+ return new Proxy(knownConnectionMethods, {
54
+ get: (target, property, receiver) => {
55
+ if (typeof property === "string" && !(property in target)) {
56
+ return (..._args) => {
57
+ throw new Error(`${serviceName} connection shim does not implement "${property}". Update ${serviceName}Live for the current Anchor requirements.`);
58
+ };
59
+ }
60
+ return Reflect.get(target, property, receiver);
61
+ },
62
+ });
63
+ }
64
+ //# sourceMappingURL=anchor-helpers.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"anchor-helpers.js","sourceRoot":"","sources":["../../../src/program/internal/anchor-helpers.ts"],"names":[],"mappings":"AAaA,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,MAAM,OAAO,CAAC;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAMhC,MAAM,UAAU,WAAW,CAAC,OAAyB;IACnD,OAAO,IAAI,SAAS,CAAC,OAAO,CAAC,CAAC;AAChC,CAAC;AAKD,MAAM,UAAU,gBAAgB,CAAC,QAAqB;IACpD,MAAM,MAAM,GAA8B,EAAE,CAAC;IAC7C,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,EAAE,CAAC;QACpD,MAAM,CAAC,GAAG,CAAC,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IACnC,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAMD,MAAM,UAAU,YAAY,CAAC,IAAwB;IACnD,OAAO,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,EAAE,EAAE;QACtB,IAAI,OAAO,GAAG,KAAK,QAAQ,EAAE,CAAC;YAC5B,OAAO,IAAI,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,MAAM,CAAC,SAAS,CAAC,GAAG,CAAC,EAAE,CAAC;YACrD,OAAO,IAAI,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,CAAC,CAAC;QAChC,CAAC;QACD,OAAO,GAAG,CAAC;IACb,CAAC,CAAC,CAAC;AACL,CAAC;AAUD,MAAM,UAAU,oBAAoB,CAAC,OAAe;IAClD,OAAO,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;AACxC,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAA4B;IAC5D,MAAM,CAAC,WAAW,CAAC,GAAG,KAAK,CAAC,IAAI,CAAC;IAEjC,OAAO;QACL,IAAI,EAAE,oBAAoB,CAAC,WAAW,CAAC;QACvC,UAAU,EAAE,KAAK,CAAC,UAAU;QAG5B,QAAQ,EAAE,MAAM,CAAC,KAAK,CAAC,QAAQ,CAAC;QAChC,KAAK,EAAE,WAAW,CAAC,KAAK,CAAC,KAAK,CAAC;QAC/B,SAAS,EAAE,MAAM,CAAC,KAAK,CAAC,SAAS,IAAI,CAAC,CAAC;KACxC,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,yBAAyB,CACvC,GAAsB,EACtB,WAA8C;IAE9C,MAAM,sBAAsB,GAAG;QAC7B,cAAc,EAAE,KAAK,EAAE,MAAiB,EAAE,EAAE;YAC1C,MAAM,QAAQ,GAAG,MAAM,GAAG;iBACvB,cAAc,CAAC,MAAM,CAAC,QAAQ,EAAa,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,CAAC;iBACpE,IAAI,EAAE,CAAC;YACV,OAAO,QAAQ,CAAC,KAAK,KAAK,IAAI;gBAC5B,CAAC,CAAC,IAAI;gBACN,CAAC,CAAC,iBAAiB,CAAC,QAAQ,CAAC,KAA8B,CAAC,CAAC;QACjE,CAAC;QACD,kBAAkB,EAAE,KAAK,IAAI,EAAE;YAC7B,MAAM,EAAE,SAAS,EAAE,oBAAoB,EAAE,GAAG,CAAC,MAAM,GAAG,CAAC,kBAAkB,EAAE,CAAC,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC;YAC1F,OAAO,EAAE,SAAS,EAAE,oBAAoB,EAAE,MAAM,CAAC,oBAAoB,CAAC,EAAE,CAAC;QAC3E,CAAC;KACF,CAAC;IAEF,OAAO,IAAI,KAAK,CAAC,sBAAsB,EAAE;QACvC,GAAG,EAAE,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,EAAE,EAAE;YAClC,IAAI,OAAO,QAAQ,KAAK,QAAQ,IAAI,CAAC,CAAC,QAAQ,IAAI,MAAM,CAAC,EAAE,CAAC;gBAC1D,OAAO,CAAC,GAAG,KAAgB,EAAE,EAAE;oBAC7B,MAAM,IAAI,KAAK,CACb,GAAG,WAAW,wCAAwC,QAAQ,aAAa,WAAW,2CAA2C,CAClI,CAAC;gBACJ,CAAC,CAAC;YACJ,CAAC;YAED,OAAO,OAAO,CAAC,GAAG,CAAC,MAAM,EAAE,QAAQ,EAAE,QAAQ,CAAC,CAAC;QACjD,CAAC;KACF,CAAiD,CAAC;AACrD,CAAC","sourcesContent":["/**\n * Shared helpers for Anchor program interaction.\n *\n * Used by both ProgramWriter and ProgramReader to convert between\n * Solana kit types and Anchor's legacy @solana/web3.js types.\n *\n * @internal\n */\n\nimport type { Program } from \"@coral-xyz/anchor\";\nimport type { Address } from \"@solana/addresses\";\nimport type { Rpc, SolanaRpcApi } from \"@solana/kit\";\nimport type { AccountInfo } from \"@solana/web3.js\";\nimport { PublicKey } from \"@solana/web3.js\";\nimport BN from \"bn.js\";\nimport { Buffer } from \"buffer\";\nimport type { AccountsMap } from \"../types.js\";\n\n/**\n * Convert a string/Address to PublicKey.\n */\nexport function toPublicKey(address: Address | string): PublicKey {\n return new PublicKey(address);\n}\n\n/**\n * Convert account map values to PublicKeys for Anchor.\n */\nexport function toAnchorAccounts(accounts: AccountsMap): Record<string, PublicKey> {\n const result: Record<string, PublicKey> = {};\n for (const [key, value] of Object.entries(accounts)) {\n result[key] = toPublicKey(value);\n }\n return result;\n}\n\n/**\n * Convert args to Anchor-compatible format.\n * Handles bigint and integer number -> BN conversion for borsh integer layouts.\n */\nexport function toAnchorArgs(args: readonly unknown[]): unknown[] {\n return args.map((arg) => {\n if (typeof arg === \"bigint\") {\n return new BN(arg.toString());\n }\n if (typeof arg === \"number\" && Number.isInteger(arg)) {\n return new BN(arg.toString());\n }\n return arg;\n });\n}\n\nexport type Base64AccountInfoLike = Readonly<{\n data: readonly [string, string];\n executable: boolean;\n lamports: bigint | number;\n owner: Address;\n rentEpoch?: bigint | number;\n}>;\n\nexport function decodeBase64ToBuffer(encoded: string): Buffer {\n return Buffer.from(encoded, \"base64\");\n}\n\nexport function toWeb3AccountInfo(value: Base64AccountInfoLike): AccountInfo<Buffer> {\n const [encodedData] = value.data;\n\n return {\n data: decodeBase64ToBuffer(encodedData),\n executable: value.executable,\n // web3.js AccountInfo requires number lamports. Values above Number.MAX_SAFE_INTEGER\n // can lose precision during conversion, but this boundary is required for compatibility.\n lamports: Number(value.lamports),\n owner: toPublicKey(value.owner),\n rentEpoch: Number(value.rentEpoch ?? 0),\n };\n}\n\nexport function makeProgramConnectionShim(\n rpc: Rpc<SolanaRpcApi>,\n serviceName: \"ProgramReader\" | \"ProgramWriter\"\n): Program[\"provider\"][\"connection\"] {\n const knownConnectionMethods = {\n getAccountInfo: async (pubkey: PublicKey) => {\n const response = await rpc\n .getAccountInfo(pubkey.toBase58() as Address, { encoding: \"base64\" })\n .send();\n return response.value === null\n ? null\n : toWeb3AccountInfo(response.value as Base64AccountInfoLike);\n },\n getLatestBlockhash: async () => {\n const { blockhash, lastValidBlockHeight } = (await rpc.getLatestBlockhash().send()).value;\n return { blockhash, lastValidBlockHeight: Number(lastValidBlockHeight) };\n },\n };\n\n return new Proxy(knownConnectionMethods, {\n get: (target, property, receiver) => {\n if (typeof property === \"string\" && !(property in target)) {\n return (..._args: unknown[]) => {\n throw new Error(\n `${serviceName} connection shim does not implement \"${property}\". Update ${serviceName}Live for the current Anchor requirements.`\n );\n };\n }\n\n return Reflect.get(target, property, receiver);\n },\n }) as unknown as Program[\"provider\"][\"connection\"];\n}\n"]}
@@ -0,0 +1,19 @@
1
+ import type { Idl } from "@coral-xyz/anchor";
2
+ import { Program } from "@coral-xyz/anchor";
3
+ import { Context, Effect, Layer } from "effect";
4
+ import { WalletNotConnectedError } from "#src/core/errors/index.js";
5
+ import { RpcService } from "#src/rpc/index.js";
6
+ import { SignerService } from "#src/signer/index.js";
7
+ import type { CreateProgramParams, ViewParams } from "./types.js";
8
+ import { InstructionNotFoundError, ProgramCreationError, ProgramReadError, ViewNotSupportedError } from "./types.js";
9
+ export type ProgramReaderShape = {
10
+ readonly createProgram: <T extends Idl>(params: CreateProgramParams<T>) => Effect.Effect<Program<T>, ProgramCreationError | WalletNotConnectedError>;
11
+ readonly view: (params: ViewParams) => Effect.Effect<unknown, ProgramCreationError | InstructionNotFoundError | ViewNotSupportedError | ProgramReadError | WalletNotConnectedError>;
12
+ readonly viewWithProgram: <T extends Idl>(program: Program<T>, params: Pick<ViewParams, "method" | "args" | "accounts">) => Effect.Effect<unknown, InstructionNotFoundError | ViewNotSupportedError | ProgramReadError | WalletNotConnectedError>;
13
+ };
14
+ declare const ProgramReader_base: Context.TagClass<ProgramReader, "esolana/ProgramReader", ProgramReaderShape>;
15
+ export declare class ProgramReader extends ProgramReader_base {
16
+ }
17
+ export declare const ProgramReaderLive: Layer.Layer<ProgramReader, never, RpcService | SignerService>;
18
+ export {};
19
+ //# sourceMappingURL=reader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"reader.d.ts","sourceRoot":"","sources":["../../src/program/reader.ts"],"names":[],"mappings":"AAYA,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,mBAAmB,CAAC;AAC7C,OAAO,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAc5C,OAAO,EAAS,OAAO,EAAE,MAAM,EAAQ,KAAK,EAAmB,MAAM,QAAQ,CAAC;AAC9E,OAAO,EAAE,uBAAuB,EAAE,MAAM,2BAA2B,CAAC;AACpE,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAC/C,OAAO,EAAE,aAAa,EAAE,MAAM,sBAAsB,CAAC;AAQrD,OAAO,KAAK,EAAE,mBAAmB,EAAE,UAAU,EAAE,MAAM,YAAY,CAAC;AAClE,OAAO,EACL,wBAAwB,EACxB,oBAAoB,EACpB,gBAAgB,EAChB,qBAAqB,EACtB,MAAM,YAAY,CAAC;AA2RpB,MAAM,MAAM,kBAAkB,GAAG;IAO/B,QAAQ,CAAC,aAAa,EAAE,CAAC,CAAC,SAAS,GAAG,EACpC,MAAM,EAAE,mBAAmB,CAAC,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,oBAAoB,GAAG,uBAAuB,CAAC,CAAC;IAQ/E,QAAQ,CAAC,IAAI,EAAE,CACb,MAAM,EAAE,UAAU,KACf,MAAM,CAAC,MAAM,CAChB,OAAO,EACL,oBAAoB,GACpB,wBAAwB,GACxB,qBAAqB,GACrB,gBAAgB,GAChB,uBAAuB,CAC1B,CAAC;IAOF,QAAQ,CAAC,eAAe,EAAE,CAAC,CAAC,SAAS,GAAG,EACtC,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,EACnB,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC,KACrD,MAAM,CAAC,MAAM,CAChB,OAAO,EACP,wBAAwB,GAAG,qBAAqB,GAAG,gBAAgB,GAAG,uBAAuB,CAC9F,CAAC;CACH,CAAC;;AAOF,qBAAa,aAAc,SAAQ,kBAGhC;CAAG;AAcN,eAAO,MAAM,iBAAiB,+DA+I7B,CAAC"}