@prb/effect-solana 1.0.0-beta.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.
- package/README.md +406 -0
- package/dist/balance/index.d.ts +2 -0
- package/dist/balance/index.d.ts.map +1 -0
- package/dist/balance/index.js +2 -0
- package/dist/balance/index.js.map +1 -0
- package/dist/balance/service.d.ts +21 -0
- package/dist/balance/service.d.ts.map +1 -0
- package/dist/balance/service.js +62 -0
- package/dist/balance/service.js.map +1 -0
- package/dist/constants/index.d.ts +11 -0
- package/dist/constants/index.d.ts.map +1 -0
- package/dist/constants/index.js +14 -0
- package/dist/constants/index.js.map +1 -0
- package/dist/core/errors/account.d.ts +21 -0
- package/dist/core/errors/account.d.ts.map +1 -0
- package/dist/core/errors/account.js +14 -0
- package/dist/core/errors/account.js.map +1 -0
- package/dist/core/errors/index.d.ts +6 -0
- package/dist/core/errors/index.d.ts.map +1 -0
- package/dist/core/errors/index.js +6 -0
- package/dist/core/errors/index.js.map +1 -0
- package/dist/core/errors/predicates.d.ts +21 -0
- package/dist/core/errors/predicates.d.ts.map +1 -0
- package/dist/core/errors/predicates.js +8 -0
- package/dist/core/errors/predicates.js.map +1 -0
- package/dist/core/errors/rpc.d.ts +20 -0
- package/dist/core/errors/rpc.d.ts.map +1 -0
- package/dist/core/errors/rpc.js +13 -0
- package/dist/core/errors/rpc.js.map +1 -0
- package/dist/core/errors/transaction.d.ts +46 -0
- package/dist/core/errors/transaction.d.ts.map +1 -0
- package/dist/core/errors/transaction.js +30 -0
- package/dist/core/errors/transaction.js.map +1 -0
- package/dist/core/errors/wallet.d.ts +25 -0
- package/dist/core/errors/wallet.d.ts.map +1 -0
- package/dist/core/errors/wallet.js +15 -0
- package/dist/core/errors/wallet.js.map +1 -0
- package/dist/core/index.d.ts +2 -0
- package/dist/core/index.d.ts.map +1 -0
- package/dist/core/index.js +2 -0
- package/dist/core/index.js.map +1 -0
- package/dist/index.d.ts +13 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +13 -0
- package/dist/index.js.map +1 -0
- package/dist/internal/index.d.ts +2 -0
- package/dist/internal/index.d.ts.map +1 -0
- package/dist/internal/index.js +2 -0
- package/dist/internal/index.js.map +1 -0
- package/dist/internal/kit-effect.d.ts +11 -0
- package/dist/internal/kit-effect.d.ts.map +1 -0
- package/dist/internal/kit-effect.js +19 -0
- package/dist/internal/kit-effect.js.map +1 -0
- package/dist/pda/index.d.ts +2 -0
- package/dist/pda/index.d.ts.map +1 -0
- package/dist/pda/index.js +2 -0
- package/dist/pda/index.js.map +1 -0
- package/dist/pda/service.d.ts +15 -0
- package/dist/pda/service.d.ts.map +1 -0
- package/dist/pda/service.js +34 -0
- package/dist/pda/service.js.map +1 -0
- package/dist/presets/index.d.ts +2 -0
- package/dist/presets/index.d.ts.map +1 -0
- package/dist/presets/index.js +2 -0
- package/dist/presets/index.js.map +1 -0
- package/dist/presets/layers.d.ts +18 -0
- package/dist/presets/layers.d.ts.map +1 -0
- package/dist/presets/layers.js +40 -0
- package/dist/presets/layers.js.map +1 -0
- package/dist/react-hooks/index.d.ts +9 -0
- package/dist/react-hooks/index.d.ts.map +1 -0
- package/dist/react-hooks/index.js +5 -0
- package/dist/react-hooks/index.js.map +1 -0
- package/dist/react-hooks/internal/error.d.ts +5 -0
- package/dist/react-hooks/internal/error.d.ts.map +1 -0
- package/dist/react-hooks/internal/error.js +9 -0
- package/dist/react-hooks/internal/error.js.map +1 -0
- package/dist/react-hooks/internal/is-dev.d.ts +2 -0
- package/dist/react-hooks/internal/is-dev.d.ts.map +1 -0
- package/dist/react-hooks/internal/is-dev.js +5 -0
- package/dist/react-hooks/internal/is-dev.js.map +1 -0
- package/dist/react-hooks/internal/runtime.d.ts +21 -0
- package/dist/react-hooks/internal/runtime.d.ts.map +1 -0
- package/dist/react-hooks/internal/runtime.js +38 -0
- package/dist/react-hooks/internal/runtime.js.map +1 -0
- package/dist/react-hooks/internal/scoped-run.d.ts +11 -0
- package/dist/react-hooks/internal/scoped-run.d.ts.map +1 -0
- package/dist/react-hooks/internal/scoped-run.js +21 -0
- package/dist/react-hooks/internal/scoped-run.js.map +1 -0
- package/dist/react-hooks/internal/stable.d.ts +2 -0
- package/dist/react-hooks/internal/stable.d.ts.map +1 -0
- package/dist/react-hooks/internal/stable.js +3 -0
- package/dist/react-hooks/internal/stable.js.map +1 -0
- package/dist/react-hooks/primitives/use-effect-memo-factory.d.ts +11 -0
- package/dist/react-hooks/primitives/use-effect-memo-factory.d.ts.map +1 -0
- package/dist/react-hooks/primitives/use-effect-memo-factory.js +92 -0
- package/dist/react-hooks/primitives/use-effect-memo-factory.js.map +1 -0
- package/dist/react-hooks/primitives/use-effect.d.ts +23 -0
- package/dist/react-hooks/primitives/use-effect.d.ts.map +1 -0
- package/dist/react-hooks/primitives/use-effect.js +93 -0
- package/dist/react-hooks/primitives/use-effect.js.map +1 -0
- package/dist/react-hooks/primitives/use-fork-effect.d.ts +4 -0
- package/dist/react-hooks/primitives/use-fork-effect.d.ts.map +1 -0
- package/dist/react-hooks/primitives/use-fork-effect.js +20 -0
- package/dist/react-hooks/primitives/use-fork-effect.js.map +1 -0
- package/dist/react-hooks/primitives/use-stream.d.ts +26 -0
- package/dist/react-hooks/primitives/use-stream.d.ts.map +1 -0
- package/dist/react-hooks/primitives/use-stream.js +161 -0
- package/dist/react-hooks/primitives/use-stream.js.map +1 -0
- package/dist/react-hooks/primitives.d.ts +8 -0
- package/dist/react-hooks/primitives.d.ts.map +1 -0
- package/dist/react-hooks/primitives.js +6 -0
- package/dist/react-hooks/primitives.js.map +1 -0
- package/dist/react-hooks/provider.d.ts +19 -0
- package/dist/react-hooks/provider.d.ts.map +1 -0
- package/dist/react-hooks/provider.js +71 -0
- package/dist/react-hooks/provider.js.map +1 -0
- package/dist/rpc/index.d.ts +2 -0
- package/dist/rpc/index.d.ts.map +1 -0
- package/dist/rpc/index.js +2 -0
- package/dist/rpc/index.js.map +1 -0
- package/dist/rpc/service.d.ts +17 -0
- package/dist/rpc/service.d.ts.map +1 -0
- package/dist/rpc/service.js +35 -0
- package/dist/rpc/service.js.map +1 -0
- package/dist/signer/index.d.ts +2 -0
- package/dist/signer/index.d.ts.map +1 -0
- package/dist/signer/index.js +2 -0
- package/dist/signer/index.js.map +1 -0
- package/dist/signer/service.d.ts +22 -0
- package/dist/signer/service.d.ts.map +1 -0
- package/dist/signer/service.js +42 -0
- package/dist/signer/service.js.map +1 -0
- package/dist/telemetry/index.d.ts +3 -0
- package/dist/telemetry/index.d.ts.map +1 -0
- package/dist/telemetry/index.js +3 -0
- package/dist/telemetry/index.js.map +1 -0
- package/dist/telemetry/logger.d.ts +30 -0
- package/dist/telemetry/logger.d.ts.map +1 -0
- package/dist/telemetry/logger.js +8 -0
- package/dist/telemetry/logger.js.map +1 -0
- package/dist/telemetry/tracer.d.ts +47 -0
- package/dist/telemetry/tracer.d.ts.map +1 -0
- package/dist/telemetry/tracer.js +47 -0
- package/dist/telemetry/tracer.js.map +1 -0
- package/dist/testing-kit/_fixtures/addresses.d.ts +8 -0
- package/dist/testing-kit/_fixtures/addresses.d.ts.map +1 -0
- package/dist/testing-kit/_fixtures/addresses.js +7 -0
- package/dist/testing-kit/_fixtures/addresses.js.map +1 -0
- package/dist/testing-kit/helpers.d.ts +9 -0
- package/dist/testing-kit/helpers.d.ts.map +1 -0
- package/dist/testing-kit/helpers.js +32 -0
- package/dist/testing-kit/helpers.js.map +1 -0
- package/dist/testing-kit/index.d.ts +17 -0
- package/dist/testing-kit/index.d.ts.map +1 -0
- package/dist/testing-kit/index.js +10 -0
- package/dist/testing-kit/index.js.map +1 -0
- package/dist/testing-kit/mock-balance-service.d.ts +18 -0
- package/dist/testing-kit/mock-balance-service.d.ts.map +1 -0
- package/dist/testing-kit/mock-balance-service.js +10 -0
- package/dist/testing-kit/mock-balance-service.js.map +1 -0
- package/dist/testing-kit/mock-pda-service.d.ts +12 -0
- package/dist/testing-kit/mock-pda-service.d.ts.map +1 -0
- package/dist/testing-kit/mock-pda-service.js +11 -0
- package/dist/testing-kit/mock-pda-service.js.map +1 -0
- package/dist/testing-kit/mock-rpc-service.d.ts +15 -0
- package/dist/testing-kit/mock-rpc-service.d.ts.map +1 -0
- package/dist/testing-kit/mock-rpc-service.js +63 -0
- package/dist/testing-kit/mock-rpc-service.js.map +1 -0
- package/dist/testing-kit/mock-signer-service.d.ts +16 -0
- package/dist/testing-kit/mock-signer-service.d.ts.map +1 -0
- package/dist/testing-kit/mock-signer-service.js +25 -0
- package/dist/testing-kit/mock-signer-service.js.map +1 -0
- package/dist/testing-kit/mock-token-service.d.ts +28 -0
- package/dist/testing-kit/mock-token-service.d.ts.map +1 -0
- package/dist/testing-kit/mock-token-service.js +51 -0
- package/dist/testing-kit/mock-token-service.js.map +1 -0
- package/dist/testing-kit/mock-transaction-service.d.ts +22 -0
- package/dist/testing-kit/mock-transaction-service.d.ts.map +1 -0
- package/dist/testing-kit/mock-transaction-service.js +29 -0
- package/dist/testing-kit/mock-transaction-service.js.map +1 -0
- package/dist/testing-kit/test-layer.d.ts +23 -0
- package/dist/testing-kit/test-layer.d.ts.map +1 -0
- package/dist/testing-kit/test-layer.js +31 -0
- package/dist/testing-kit/test-layer.js.map +1 -0
- package/dist/token/index.d.ts +2 -0
- package/dist/token/index.d.ts.map +1 -0
- package/dist/token/index.js +2 -0
- package/dist/token/index.js.map +1 -0
- package/dist/token/service.d.ts +38 -0
- package/dist/token/service.d.ts.map +1 -0
- package/dist/token/service.js +158 -0
- package/dist/token/service.js.map +1 -0
- package/dist/tx/index.d.ts +3 -0
- package/dist/tx/index.d.ts.map +1 -0
- package/dist/tx/index.js +3 -0
- package/dist/tx/index.js.map +1 -0
- package/dist/tx/service.d.ts +27 -0
- package/dist/tx/service.d.ts.map +1 -0
- package/dist/tx/service.js +178 -0
- package/dist/tx/service.js.map +1 -0
- package/dist/tx/types.d.ts +29 -0
- package/dist/tx/types.d.ts.map +1 -0
- package/dist/tx/types.js +2 -0
- package/dist/tx/types.js.map +1 -0
- package/dist/types/index.d.ts +12 -0
- package/dist/types/index.d.ts.map +1 -0
- package/dist/types/index.js +2 -0
- package/dist/types/index.js.map +1 -0
- package/package.json +81 -0
package/README.md
ADDED
|
@@ -0,0 +1,406 @@
|
|
|
1
|
+
# @prb/effect-solana
|
|
2
|
+
|
|
3
|
+
Effect-TS integration for the Solana blockchain ecosystem.
|
|
4
|
+
|
|
5
|
+
## Installation
|
|
6
|
+
|
|
7
|
+
```bash
|
|
8
|
+
npm install @prb/effect-solana effect @solana/kit
|
|
9
|
+
# or
|
|
10
|
+
pnpm add @prb/effect-solana effect @solana/kit
|
|
11
|
+
# or
|
|
12
|
+
bun add @prb/effect-solana effect @solana/kit
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
## Quick Start
|
|
16
|
+
|
|
17
|
+
```typescript
|
|
18
|
+
import { Effect, Layer } from "effect";
|
|
19
|
+
import { BalanceService, BalanceServiceLive, RpcService, RpcServiceLive } from "@prb/effect-solana";
|
|
20
|
+
import type { Address } from "@solana/kit";
|
|
21
|
+
|
|
22
|
+
// Create a custom RPC layer
|
|
23
|
+
const MyRpcLayer = Layer.succeed(RpcService, {
|
|
24
|
+
getRpc: () => Effect.succeed(/* your RPC client */),
|
|
25
|
+
getRpcUrl: () => Effect.succeed("https://api.devnet.solana.com"),
|
|
26
|
+
});
|
|
27
|
+
|
|
28
|
+
// Compose with BalanceService
|
|
29
|
+
const MainLayer = BalanceServiceLive.pipe(Layer.provide(MyRpcLayer));
|
|
30
|
+
|
|
31
|
+
// Read SOL balance
|
|
32
|
+
const program = Effect.gen(function* () {
|
|
33
|
+
const balance = yield* BalanceService;
|
|
34
|
+
const address = "YOUR_ADDRESS" as Address;
|
|
35
|
+
const sol = yield* balance.getSolBalance(address);
|
|
36
|
+
console.log(`Balance: ${sol} lamports`);
|
|
37
|
+
});
|
|
38
|
+
|
|
39
|
+
Effect.runPromise(Effect.provide(program, MainLayer));
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
## Services
|
|
43
|
+
|
|
44
|
+
### RpcService
|
|
45
|
+
|
|
46
|
+
Manages Solana RPC client per cluster.
|
|
47
|
+
|
|
48
|
+
```typescript
|
|
49
|
+
import { RpcService } from "@prb/effect-solana";
|
|
50
|
+
|
|
51
|
+
const program = Effect.gen(function* () {
|
|
52
|
+
const rpcService = yield* RpcService;
|
|
53
|
+
const rpc = yield* rpcService.getRpc();
|
|
54
|
+
const url = yield* rpcService.getRpcUrl();
|
|
55
|
+
});
|
|
56
|
+
```
|
|
57
|
+
|
|
58
|
+
### SignerService
|
|
59
|
+
|
|
60
|
+
Wallet signing interface (adapter-agnostic).
|
|
61
|
+
|
|
62
|
+
```typescript
|
|
63
|
+
import { SignerService } from "@prb/effect-solana";
|
|
64
|
+
|
|
65
|
+
const program = Effect.gen(function* () {
|
|
66
|
+
const signer = yield* SignerService;
|
|
67
|
+
const address = yield* signer.getAddress();
|
|
68
|
+
const signed = yield* signer.signTransaction(tx);
|
|
69
|
+
});
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
### BalanceService
|
|
73
|
+
|
|
74
|
+
SOL balance queries and monitoring.
|
|
75
|
+
|
|
76
|
+
```typescript
|
|
77
|
+
import { BalanceService } from "@prb/effect-solana";
|
|
78
|
+
|
|
79
|
+
const program = Effect.gen(function* () {
|
|
80
|
+
const balance = yield* BalanceService;
|
|
81
|
+
|
|
82
|
+
// Get balance
|
|
83
|
+
const sol = yield* balance.getSolBalance(address);
|
|
84
|
+
|
|
85
|
+
// Check sufficient balance
|
|
86
|
+
const hasFunds = yield* balance.hasSufficientBalance({
|
|
87
|
+
address,
|
|
88
|
+
required: 1_000_000_000n,
|
|
89
|
+
});
|
|
90
|
+
|
|
91
|
+
// Watch balance changes
|
|
92
|
+
const stream = yield* balance.watchBalance({
|
|
93
|
+
address,
|
|
94
|
+
pollingInterval: 5000,
|
|
95
|
+
});
|
|
96
|
+
});
|
|
97
|
+
```
|
|
98
|
+
|
|
99
|
+
### TokenService
|
|
100
|
+
|
|
101
|
+
SPL token operations.
|
|
102
|
+
|
|
103
|
+
```typescript
|
|
104
|
+
import { TokenService } from "@prb/effect-solana";
|
|
105
|
+
|
|
106
|
+
const program = Effect.gen(function* () {
|
|
107
|
+
const token = yield* TokenService;
|
|
108
|
+
|
|
109
|
+
// Get associated token address
|
|
110
|
+
const ata = yield* token.getAssociatedTokenAddress({ owner, mint });
|
|
111
|
+
|
|
112
|
+
// Token-2022: pass tokenProgram to work with Token-2022 mints
|
|
113
|
+
const ata2022 = yield* token.getAssociatedTokenAddress({
|
|
114
|
+
owner,
|
|
115
|
+
mint,
|
|
116
|
+
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
|
|
117
|
+
});
|
|
118
|
+
|
|
119
|
+
// Get or create ATA
|
|
120
|
+
const { address, instruction } = yield* token.getOrCreateATA({ owner, mint, payer });
|
|
121
|
+
|
|
122
|
+
// Get token balance
|
|
123
|
+
const balance = yield* token.getTokenBalance(ata);
|
|
124
|
+
|
|
125
|
+
// Get mint account
|
|
126
|
+
const mint = yield* token.getMint(params.mint);
|
|
127
|
+
|
|
128
|
+
// Get token account
|
|
129
|
+
const account = yield* token.getTokenAccount(ata);
|
|
130
|
+
|
|
131
|
+
// Build transfer instruction
|
|
132
|
+
const transfer = yield* token.getTransferInstruction({
|
|
133
|
+
source: ata,
|
|
134
|
+
destination: recipientAta,
|
|
135
|
+
authority: owner,
|
|
136
|
+
amount: 1_000_000n,
|
|
137
|
+
});
|
|
138
|
+
|
|
139
|
+
const transfer2022 = yield* token.getTransferInstruction({
|
|
140
|
+
source: ata2022,
|
|
141
|
+
destination: recipientAta2022,
|
|
142
|
+
authority: owner,
|
|
143
|
+
amount: 1_000_000n,
|
|
144
|
+
tokenProgram: TOKEN_2022_PROGRAM_ADDRESS,
|
|
145
|
+
});
|
|
146
|
+
|
|
147
|
+
// Check if token account exists
|
|
148
|
+
const exists = yield* token.tokenAccountExists(ata);
|
|
149
|
+
});
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
### TransactionService
|
|
153
|
+
|
|
154
|
+
Transaction lifecycle management.
|
|
155
|
+
|
|
156
|
+
```typescript
|
|
157
|
+
import { TransactionService } from "@prb/effect-solana";
|
|
158
|
+
|
|
159
|
+
const program = Effect.gen(function* () {
|
|
160
|
+
const tx = yield* TransactionService;
|
|
161
|
+
|
|
162
|
+
// Build transaction
|
|
163
|
+
const message = yield* tx.build(instructions, {
|
|
164
|
+
computeBudget: { unitLimit: 600_000, microLamports: 10_000 },
|
|
165
|
+
});
|
|
166
|
+
|
|
167
|
+
// Sign transaction
|
|
168
|
+
const signed = yield* tx.sign(message);
|
|
169
|
+
|
|
170
|
+
// Send transaction
|
|
171
|
+
const signature = yield* tx.send(signed);
|
|
172
|
+
|
|
173
|
+
// Confirm transaction
|
|
174
|
+
const receipt = yield* tx.confirm(signature, {
|
|
175
|
+
commitment: "confirmed",
|
|
176
|
+
timeout: 60_000,
|
|
177
|
+
});
|
|
178
|
+
|
|
179
|
+
// Or do all at once
|
|
180
|
+
const receipt2 = yield* tx.sendAndConfirm(instructions, {
|
|
181
|
+
commitment: "confirmed",
|
|
182
|
+
});
|
|
183
|
+
|
|
184
|
+
// Batch send and confirm
|
|
185
|
+
const receipts = yield* tx.sendAndConfirmBatch(
|
|
186
|
+
[{ instructions }, { instructions: [instruction2], computeBudget: { unitLimit: 300_000 } }],
|
|
187
|
+
{ concurrency: 2, confirm: { commitment: "confirmed" } },
|
|
188
|
+
);
|
|
189
|
+
|
|
190
|
+
// Simulate before sending
|
|
191
|
+
yield* tx.simulate(message);
|
|
192
|
+
});
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
### PdaService
|
|
196
|
+
|
|
197
|
+
Program Derived Address utilities.
|
|
198
|
+
|
|
199
|
+
```typescript
|
|
200
|
+
import { PdaService } from "@prb/effect-solana";
|
|
201
|
+
|
|
202
|
+
const program = Effect.gen(function* () {
|
|
203
|
+
const pda = yield* PdaService;
|
|
204
|
+
const [address, bump] = yield* pda.derive(seeds, programId);
|
|
205
|
+
});
|
|
206
|
+
```
|
|
207
|
+
|
|
208
|
+
## Layer Composition
|
|
209
|
+
|
|
210
|
+
Compose services to build your application layer:
|
|
211
|
+
|
|
212
|
+
```typescript
|
|
213
|
+
import { Layer } from "effect";
|
|
214
|
+
import {
|
|
215
|
+
BalanceServiceLive,
|
|
216
|
+
RpcServiceLive,
|
|
217
|
+
SignerServiceLive,
|
|
218
|
+
TokenServiceLive,
|
|
219
|
+
TransactionServiceLive,
|
|
220
|
+
} from "@prb/effect-solana";
|
|
221
|
+
|
|
222
|
+
// Create custom implementations
|
|
223
|
+
const MyRpcLayer = Layer.succeed(RpcService, {
|
|
224
|
+
getRpc: () => Effect.succeed(/* ... */),
|
|
225
|
+
getRpcUrl: () => Effect.succeed("https://api.devnet.solana.com"),
|
|
226
|
+
});
|
|
227
|
+
|
|
228
|
+
const MySignerLayer = Layer.succeed(SignerService, {
|
|
229
|
+
getAddress: () => Effect.succeed(/* ... */),
|
|
230
|
+
signTransaction: (tx) => Effect.succeed(/* ... */),
|
|
231
|
+
});
|
|
232
|
+
|
|
233
|
+
// Compose layers
|
|
234
|
+
const AppLayer = Layer.mergeAll(BalanceServiceLive, TokenServiceLive, TransactionServiceLive).pipe(
|
|
235
|
+
Layer.provide(Layer.merge(MyRpcLayer, MySignerLayer)),
|
|
236
|
+
);
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
## Constants
|
|
240
|
+
|
|
241
|
+
The library exports common Solana constants:
|
|
242
|
+
|
|
243
|
+
```typescript
|
|
244
|
+
import {
|
|
245
|
+
LAMPORTS_PER_SOL,
|
|
246
|
+
ClusterEndpoints,
|
|
247
|
+
SYSTEM_PROGRAM_ADDRESS,
|
|
248
|
+
TOKEN_PROGRAM_ADDRESS,
|
|
249
|
+
TOKEN_2022_PROGRAM_ADDRESS,
|
|
250
|
+
ASSOCIATED_TOKEN_PROGRAM_ADDRESS,
|
|
251
|
+
COMPUTE_BUDGET_PROGRAM_ADDRESS,
|
|
252
|
+
MEMO_PROGRAM_ADDRESS,
|
|
253
|
+
} from "@prb/effect-solana";
|
|
254
|
+
|
|
255
|
+
// Use cluster endpoints
|
|
256
|
+
const devnetUrl = ClusterEndpoints.devnet;
|
|
257
|
+
const mainnetUrl = ClusterEndpoints["mainnet-beta"];
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
## Types
|
|
261
|
+
|
|
262
|
+
Re-exported Solana types and custom definitions:
|
|
263
|
+
|
|
264
|
+
```typescript
|
|
265
|
+
import type {
|
|
266
|
+
Address,
|
|
267
|
+
Commitment,
|
|
268
|
+
Lamports,
|
|
269
|
+
Signature,
|
|
270
|
+
TransactionError,
|
|
271
|
+
Cluster,
|
|
272
|
+
ClusterConfig,
|
|
273
|
+
Microlamports,
|
|
274
|
+
} from "@prb/effect-solana";
|
|
275
|
+
```
|
|
276
|
+
|
|
277
|
+
## Error Handling
|
|
278
|
+
|
|
279
|
+
All errors are tagged for discriminated union handling:
|
|
280
|
+
|
|
281
|
+
```typescript
|
|
282
|
+
import { Effect } from "effect";
|
|
283
|
+
import { WalletNotConnectedError, TransactionFailedError, TransactionTimeoutError, RpcError } from "@prb/effect-solana";
|
|
284
|
+
|
|
285
|
+
const handled = program.pipe(
|
|
286
|
+
Effect.catchTag("WalletNotConnectedError", (e) => Effect.succeed("Please connect wallet")),
|
|
287
|
+
Effect.catchTag("TransactionFailedError", (e) => Effect.succeed(`TX failed: ${e.message}`)),
|
|
288
|
+
Effect.catchTag("TransactionTimeoutError", (e) => Effect.succeed(`TX timed out: ${e.signature}`)),
|
|
289
|
+
Effect.catchTag("RpcError", (e) => Effect.succeed(`RPC error at ${e.url}: ${e.message}`)),
|
|
290
|
+
);
|
|
291
|
+
```
|
|
292
|
+
|
|
293
|
+
## Telemetry
|
|
294
|
+
|
|
295
|
+
The library includes built-in OpenTelemetry spans for observability:
|
|
296
|
+
|
|
297
|
+
```typescript
|
|
298
|
+
import { SpanNames } from "@prb/effect-solana";
|
|
299
|
+
|
|
300
|
+
// Balance operations
|
|
301
|
+
SpanNames.BALANCE_GET_SOL;
|
|
302
|
+
SpanNames.BALANCE_WATCH_SOL;
|
|
303
|
+
|
|
304
|
+
// Transaction operations
|
|
305
|
+
SpanNames.TX_BUILD;
|
|
306
|
+
SpanNames.TX_SIGN;
|
|
307
|
+
SpanNames.TX_SEND;
|
|
308
|
+
SpanNames.TX_CONFIRM;
|
|
309
|
+
SpanNames.TX_SEND_AND_CONFIRM;
|
|
310
|
+
SpanNames.TX_SIMULATE;
|
|
311
|
+
|
|
312
|
+
// Token operations
|
|
313
|
+
SpanNames.TOKEN_GET_ATA;
|
|
314
|
+
SpanNames.TOKEN_CREATE_ATA;
|
|
315
|
+
SpanNames.TOKEN_GET_ACCOUNT;
|
|
316
|
+
|
|
317
|
+
// PDA operations
|
|
318
|
+
SpanNames.PDA_DERIVE;
|
|
319
|
+
|
|
320
|
+
// And more...
|
|
321
|
+
```
|
|
322
|
+
|
|
323
|
+
## React Integration
|
|
324
|
+
|
|
325
|
+
The library provides React hooks for integrating Solana operations into React applications:
|
|
326
|
+
|
|
327
|
+
```typescript
|
|
328
|
+
import { EffectSolanaProvider, useEffectMemo } from "@prb/effect-solana";
|
|
329
|
+
import { BalanceService } from "@prb/effect-solana";
|
|
330
|
+
import type { Address } from "@solana/kit";
|
|
331
|
+
|
|
332
|
+
function App() {
|
|
333
|
+
return (
|
|
334
|
+
<EffectSolanaProvider layer={MainLayer}>
|
|
335
|
+
<Balance address={yourAddress} />
|
|
336
|
+
</EffectSolanaProvider>
|
|
337
|
+
);
|
|
338
|
+
}
|
|
339
|
+
|
|
340
|
+
function Balance({ address }: { address: Address }) {
|
|
341
|
+
const result = useEffectMemo(
|
|
342
|
+
() =>
|
|
343
|
+
Effect.gen(function* () {
|
|
344
|
+
const balance = yield* BalanceService;
|
|
345
|
+
return yield* balance.getSolBalance(address);
|
|
346
|
+
}),
|
|
347
|
+
[address],
|
|
348
|
+
);
|
|
349
|
+
|
|
350
|
+
if (result.status === "loading") return <div>Loading...</div>;
|
|
351
|
+
if (result.status === "error") return <div>Error: {result.error.message}</div>;
|
|
352
|
+
return <div>Balance: {result.data} lamports</div>;
|
|
353
|
+
}
|
|
354
|
+
```
|
|
355
|
+
|
|
356
|
+
Available React hooks:
|
|
357
|
+
|
|
358
|
+
- `useEffectMemo` - Run an Effect with memoization
|
|
359
|
+
- `useEffectOnce` - Run an Effect once on mount
|
|
360
|
+
- `useStream` - Subscribe to an Effect Stream
|
|
361
|
+
- `useForkEffect` - Fork an Effect as a background fiber
|
|
362
|
+
- `EffectSolanaProvider` - Context provider for Effect runtime
|
|
363
|
+
- `useEffectSolanaRuntime` - Access the Effect runtime
|
|
364
|
+
|
|
365
|
+
## Examples
|
|
366
|
+
|
|
367
|
+
### Send SOL Transfer
|
|
368
|
+
|
|
369
|
+
```typescript
|
|
370
|
+
import { Effect } from "effect";
|
|
371
|
+
import { TransactionService } from "@prb/effect-solana";
|
|
372
|
+
import { getTransferSolInstruction } from "@solana-program/system";
|
|
373
|
+
|
|
374
|
+
const sendSol = (params: { from: Address; to: Address; amount: Lamports }) =>
|
|
375
|
+
Effect.gen(function* () {
|
|
376
|
+
const tx = yield* TransactionService;
|
|
377
|
+
|
|
378
|
+
const instruction = getTransferSolInstruction({
|
|
379
|
+
source: params.from,
|
|
380
|
+
destination: params.to,
|
|
381
|
+
amount: params.amount,
|
|
382
|
+
});
|
|
383
|
+
|
|
384
|
+
const receipt = yield* tx.sendAndConfirm([instruction]);
|
|
385
|
+
return receipt.signature;
|
|
386
|
+
});
|
|
387
|
+
```
|
|
388
|
+
|
|
389
|
+
### Watch Balance Changes
|
|
390
|
+
|
|
391
|
+
```typescript
|
|
392
|
+
import { Effect, Stream } from "effect";
|
|
393
|
+
import { BalanceService } from "@prb/effect-solana";
|
|
394
|
+
|
|
395
|
+
const watchBalance = (address: Address) =>
|
|
396
|
+
Effect.gen(function* () {
|
|
397
|
+
const balance = yield* BalanceService;
|
|
398
|
+
const stream = yield* balance.watchBalance({ address });
|
|
399
|
+
|
|
400
|
+
yield* Stream.runForEach(stream, (lamports) => Effect.sync(() => console.log(`Balance: ${lamports}`)));
|
|
401
|
+
});
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## License
|
|
405
|
+
|
|
406
|
+
MIT
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/balance/index.ts"],"names":[],"mappings":"AAMA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/balance/index.ts"],"names":[],"mappings":"AAMA,cAAc,cAAc,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { Address, Lamports } from "@solana/kit";
|
|
2
|
+
import { Context, Effect, Layer, Stream } from "effect";
|
|
3
|
+
import { RpcError } from "../core/errors/index.js";
|
|
4
|
+
import { RpcService } from "../rpc/index.js";
|
|
5
|
+
export type BalanceServiceShape = {
|
|
6
|
+
readonly getSolBalance: (address: Address) => Effect.Effect<Lamports, RpcError>;
|
|
7
|
+
readonly hasSufficientBalance: (params: {
|
|
8
|
+
address: Address;
|
|
9
|
+
required: Lamports;
|
|
10
|
+
}) => Effect.Effect<boolean, RpcError>;
|
|
11
|
+
readonly watchBalance: (params: {
|
|
12
|
+
address: Address;
|
|
13
|
+
pollingInterval?: number;
|
|
14
|
+
}) => Effect.Effect<Stream.Stream<Lamports, RpcError>>;
|
|
15
|
+
};
|
|
16
|
+
declare const BalanceService_base: Context.TagClass<BalanceService, "esolana/BalanceService", BalanceServiceShape>;
|
|
17
|
+
export declare class BalanceService extends BalanceService_base {
|
|
18
|
+
}
|
|
19
|
+
export declare const BalanceServiceLive: Layer.Layer<BalanceService, never, RpcService>;
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=service.d.ts.map
|
|
@@ -0,0 +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"}
|
|
@@ -0,0 +1,62 @@
|
|
|
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";
|
|
5
|
+
export class BalanceService extends Context.Tag("esolana/BalanceService")() {
|
|
6
|
+
}
|
|
7
|
+
export const BalanceServiceLive = Layer.effect(BalanceService, Effect.gen(function* () {
|
|
8
|
+
const rpcService = yield* RpcService;
|
|
9
|
+
return BalanceService.of({
|
|
10
|
+
getSolBalance: (address) => Effect.gen(function* () {
|
|
11
|
+
const rpc = yield* rpcService.getRpc();
|
|
12
|
+
const rpcUrl = yield* rpcService.getRpcUrl();
|
|
13
|
+
return yield* Effect.tryPromise({
|
|
14
|
+
catch: (cause) => new RpcError({
|
|
15
|
+
cause,
|
|
16
|
+
message: `Failed to get balance for ${address}`,
|
|
17
|
+
url: rpcUrl,
|
|
18
|
+
}),
|
|
19
|
+
try: () => rpc.getBalance(address).send(),
|
|
20
|
+
});
|
|
21
|
+
}).pipe(Effect.map((response) => response.value), Effect.withSpan(SpanNames.BALANCE_GET_SOL, {
|
|
22
|
+
attributes: { address },
|
|
23
|
+
})),
|
|
24
|
+
hasSufficientBalance: (params) => Effect.gen(function* () {
|
|
25
|
+
const rpc = yield* rpcService.getRpc();
|
|
26
|
+
const rpcUrl = yield* rpcService.getRpcUrl();
|
|
27
|
+
const response = yield* Effect.tryPromise({
|
|
28
|
+
catch: (cause) => new RpcError({
|
|
29
|
+
cause,
|
|
30
|
+
message: `Failed to get balance for ${params.address}`,
|
|
31
|
+
url: rpcUrl,
|
|
32
|
+
}),
|
|
33
|
+
try: () => rpc.getBalance(params.address).send(),
|
|
34
|
+
});
|
|
35
|
+
return response.value >= params.required;
|
|
36
|
+
}).pipe(Effect.withSpan(SpanNames.BALANCE_GET_SOL, {
|
|
37
|
+
attributes: {
|
|
38
|
+
address: params.address,
|
|
39
|
+
required: params.required.toString(),
|
|
40
|
+
},
|
|
41
|
+
})),
|
|
42
|
+
watchBalance: (params) => Effect.gen(function* () {
|
|
43
|
+
const rpc = yield* rpcService.getRpc();
|
|
44
|
+
const rpcUrl = yield* rpcService.getRpcUrl();
|
|
45
|
+
const interval = params.pollingInterval ?? 5000;
|
|
46
|
+
return Stream.repeatEffectWithSchedule(Effect.tryPromise({
|
|
47
|
+
catch: (cause) => new RpcError({
|
|
48
|
+
cause,
|
|
49
|
+
message: `Failed to poll balance for ${params.address}`,
|
|
50
|
+
url: rpcUrl,
|
|
51
|
+
}),
|
|
52
|
+
try: () => rpc.getBalance(params.address).send(),
|
|
53
|
+
}).pipe(Effect.map((response) => response.value)), Schedule.spaced(Duration.millis(interval)));
|
|
54
|
+
}).pipe(Effect.withSpan(SpanNames.BALANCE_WATCH_SOL, {
|
|
55
|
+
attributes: {
|
|
56
|
+
address: params.address,
|
|
57
|
+
pollingInterval: params.pollingInterval,
|
|
58
|
+
},
|
|
59
|
+
})),
|
|
60
|
+
});
|
|
61
|
+
}));
|
|
62
|
+
//# sourceMappingURL=service.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"service.js","sourceRoot":"","sources":["../../src/balance/service.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import type { Address } from "@solana/kit";
|
|
2
|
+
import type { Cluster } from "../types/index.js";
|
|
3
|
+
export declare const LAMPORTS_PER_SOL = 1000000000n;
|
|
4
|
+
export declare const ClusterEndpoints: Record<Cluster, string>;
|
|
5
|
+
export declare const SYSTEM_PROGRAM_ADDRESS: Address<"11111111111111111111111111111111">;
|
|
6
|
+
export declare const TOKEN_PROGRAM_ADDRESS: Address<"TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA">;
|
|
7
|
+
export declare const TOKEN_2022_PROGRAM_ADDRESS: Address<"TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb">;
|
|
8
|
+
export declare const ASSOCIATED_TOKEN_PROGRAM_ADDRESS: Address<"ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL">;
|
|
9
|
+
export declare const COMPUTE_BUDGET_PROGRAM_ADDRESS: Address<"ComputeBudget111111111111111111111111111111">;
|
|
10
|
+
export declare const MEMO_PROGRAM_ADDRESS: Address<"MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr">;
|
|
11
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAMA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAC3C,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,mBAAmB,CAAC;AAOjD,eAAO,MAAM,gBAAgB,cAAiB,CAAC;AAS/C,eAAO,MAAM,gBAAgB,EAAE,MAAM,CAAC,OAAO,EAAE,MAAM,CAKpD,CAAC;AAOF,eAAO,MAAM,sBAAsB,EACK,OAAO,CAAC,kCAAkC,CAAC,CAAC;AAGpF,eAAO,MAAM,qBAAqB,EACiB,OAAO,CAAC,6CAA6C,CAAC,CAAC;AAG1G,eAAO,MAAM,0BAA0B,EACY,OAAO,CAAC,6CAA6C,CAAC,CAAC;AAG1G,eAAO,MAAM,gCAAgC,EACO,OAAO,CAAC,8CAA8C,CAAC,CAAC;AAG5G,eAAO,MAAM,8BAA8B,EACQ,OAAO,CAAC,6CAA6C,CAAC,CAAC;AAG1G,eAAO,MAAM,oBAAoB,EACkB,OAAO,CAAC,6CAA6C,CAAC,CAAC"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export const LAMPORTS_PER_SOL = 1000000000n;
|
|
2
|
+
export const ClusterEndpoints = {
|
|
3
|
+
devnet: "https://api.devnet.solana.com",
|
|
4
|
+
localnet: "http://localhost:8899",
|
|
5
|
+
"mainnet-beta": "https://api.mainnet-beta.solana.com",
|
|
6
|
+
testnet: "https://api.testnet.solana.com",
|
|
7
|
+
};
|
|
8
|
+
export const SYSTEM_PROGRAM_ADDRESS = "11111111111111111111111111111111";
|
|
9
|
+
export const TOKEN_PROGRAM_ADDRESS = "TokenkegQfeZyiNwAJbNbGKPFXCWuBvf9Ss623VQ5DA";
|
|
10
|
+
export const TOKEN_2022_PROGRAM_ADDRESS = "TokenzQdBNbLqP5VEhdkAS6EPFLC1PHnBqCXEpPxuEb";
|
|
11
|
+
export const ASSOCIATED_TOKEN_PROGRAM_ADDRESS = "ATokenGPvbdGVxr1b2hvZbsiqW5xWH25efTNsLJA8knL";
|
|
12
|
+
export const COMPUTE_BUDGET_PROGRAM_ADDRESS = "ComputeBudget111111111111111111111111111111";
|
|
13
|
+
export const MEMO_PROGRAM_ADDRESS = "MemoSq4gqABAXKb96qnH8TysNcWxMyWCqXgDLGmfcHr";
|
|
14
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/constants/index.ts"],"names":[],"mappings":"AAcA,MAAM,CAAC,MAAM,gBAAgB,GAAG,WAAc,CAAC;AAS/C,MAAM,CAAC,MAAM,gBAAgB,GAA4B;IACvD,MAAM,EAAE,+BAA+B;IACvC,QAAQ,EAAE,uBAAuB;IACjC,cAAc,EAAE,qCAAqC;IACrD,OAAO,EAAE,gCAAgC;CAC1C,CAAC;AAOF,MAAM,CAAC,MAAM,sBAAsB,GACjC,kCAAiF,CAAC;AAGpF,MAAM,CAAC,MAAM,qBAAqB,GAChC,6CAAuG,CAAC;AAG1G,MAAM,CAAC,MAAM,0BAA0B,GACrC,6CAAuG,CAAC;AAG1G,MAAM,CAAC,MAAM,gCAAgC,GAC3C,8CAAyG,CAAC;AAG5G,MAAM,CAAC,MAAM,8BAA8B,GACzC,6CAAuG,CAAC;AAG1G,MAAM,CAAC,MAAM,oBAAoB,GAC/B,6CAAuG,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
declare const AccountNotFoundError_base: Schema.TaggedErrorClass<AccountNotFoundError, "AccountNotFoundError", {
|
|
3
|
+
readonly _tag: Schema.tag<"AccountNotFoundError">;
|
|
4
|
+
} & {
|
|
5
|
+
address: typeof Schema.String;
|
|
6
|
+
message: typeof Schema.String;
|
|
7
|
+
}>;
|
|
8
|
+
export declare class AccountNotFoundError extends AccountNotFoundError_base {
|
|
9
|
+
}
|
|
10
|
+
declare const InsufficientBalanceError_base: Schema.TaggedErrorClass<InsufficientBalanceError, "InsufficientBalanceError", {
|
|
11
|
+
readonly _tag: Schema.tag<"InsufficientBalanceError">;
|
|
12
|
+
} & {
|
|
13
|
+
address: typeof Schema.String;
|
|
14
|
+
available: typeof Schema.BigInt;
|
|
15
|
+
message: typeof Schema.String;
|
|
16
|
+
required: typeof Schema.BigInt;
|
|
17
|
+
}>;
|
|
18
|
+
export declare class InsufficientBalanceError extends InsufficientBalanceError_base {
|
|
19
|
+
}
|
|
20
|
+
export {};
|
|
21
|
+
//# sourceMappingURL=account.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.d.ts","sourceRoot":"","sources":["../../../src/core/errors/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;;;;;;;AAEhC,qBAAa,oBAAqB,SAAQ,yBAMzC;CAAG;;;;;;;;;AAEJ,qBAAa,wBAAyB,SAAQ,6BAQ7C;CAAG"}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import { Schema } from "effect";
|
|
2
|
+
export class AccountNotFoundError extends Schema.TaggedError()("AccountNotFoundError", {
|
|
3
|
+
address: Schema.String,
|
|
4
|
+
message: Schema.String,
|
|
5
|
+
}) {
|
|
6
|
+
}
|
|
7
|
+
export class InsufficientBalanceError extends Schema.TaggedError()("InsufficientBalanceError", {
|
|
8
|
+
address: Schema.String,
|
|
9
|
+
available: Schema.BigInt,
|
|
10
|
+
message: Schema.String,
|
|
11
|
+
required: Schema.BigInt,
|
|
12
|
+
}) {
|
|
13
|
+
}
|
|
14
|
+
//# sourceMappingURL=account.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"account.js","sourceRoot":"","sources":["../../../src/core/errors/account.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAEhC,MAAM,OAAO,oBAAqB,SAAQ,MAAM,CAAC,WAAW,EAAwB,CAClF,sBAAsB,EACtB;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,OAAO,EAAE,MAAM,CAAC,MAAM;CACvB,CACF;CAAG;AAEJ,MAAM,OAAO,wBAAyB,SAAQ,MAAM,CAAC,WAAW,EAA4B,CAC1F,0BAA0B,EAC1B;IACE,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,SAAS,EAAE,MAAM,CAAC,MAAM;IACxB,OAAO,EAAE,MAAM,CAAC,MAAM;IACtB,QAAQ,EAAE,MAAM,CAAC,MAAM;CACxB,CACF;CAAG"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/core/errors/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/core/errors/index.ts"],"names":[],"mappings":"AAAA,cAAc,cAAc,CAAC;AAC7B,cAAc,iBAAiB,CAAC;AAChC,cAAc,UAAU,CAAC;AACzB,cAAc,kBAAkB,CAAC;AACjC,cAAc,aAAa,CAAC"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import type { UserRejectedError } from "./wallet.js";
|
|
3
|
+
export type TaggedErrorShape = {
|
|
4
|
+
readonly _tag: string;
|
|
5
|
+
readonly message: string;
|
|
6
|
+
readonly cause?: unknown;
|
|
7
|
+
};
|
|
8
|
+
export declare const hasTaggedErrorShape: (error: unknown) => error is TaggedErrorShape;
|
|
9
|
+
export declare const isTaggedError: <T extends {
|
|
10
|
+
readonly _tag: string;
|
|
11
|
+
}>(tag: T["_tag"]) => (error: unknown) => error is T;
|
|
12
|
+
export declare const isUserRejectedError: (error: unknown) => error is UserRejectedError;
|
|
13
|
+
export declare const catchUserRejection: {
|
|
14
|
+
<A2>(fallback: A2): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A | A2, Exclude<E, UserRejectedError>, R>;
|
|
15
|
+
<A, E, R, A2>(effect: Effect.Effect<A, E, R>, fallback: A2): Effect.Effect<A | A2, Exclude<E, UserRejectedError>, R>;
|
|
16
|
+
};
|
|
17
|
+
export declare const catchUserRejectionWith: {
|
|
18
|
+
<A2, E2, R2>(fallback: Effect.Effect<A2, E2, R2>): <A, E, R>(effect: Effect.Effect<A, E, R>) => Effect.Effect<A | A2, Exclude<E, UserRejectedError> | E2, R | R2>;
|
|
19
|
+
<A, E, R, A2, E2, R2>(effect: Effect.Effect<A, E, R>, fallback: Effect.Effect<A2, E2, R2>): Effect.Effect<A | A2, Exclude<E, UserRejectedError> | E2, R | R2>;
|
|
20
|
+
};
|
|
21
|
+
//# sourceMappingURL=predicates.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicates.d.ts","sourceRoot":"","sources":["../../../src/core/errors/predicates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAGhC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,aAAa,CAAC;AAGrD,MAAM,MAAM,gBAAgB,GAAG;IAC7B,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IACtB,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;IACzB,QAAQ,CAAC,KAAK,CAAC,EAAE,OAAO,CAAC;CAC1B,CAAC;AAMF,eAAO,MAAM,mBAAmB,GAAI,OAAO,OAAO,KAAG,KAAK,IAAI,gBACoC,CAAC;AAMnG,eAAO,MAAM,aAAa,GACvB,CAAC,SAAS;IAAE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CAAE,EAAE,KAAK,CAAC,CAAC,MAAM,CAAC,MACnD,OAAO,OAAO,KAAG,KAAK,IAAI,CACuB,CAAC;AAMrD,eAAO,MAAM,mBAAmB,UAPtB,OAAO,KAAG,KAAK,qBAO+D,CAAC;AAgBzF,eAAO,MAAM,kBAAkB,EAAE;IAC/B,CAAC,EAAE,EACD,QAAQ,EAAE,EAAE,GACX,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;IAC7D,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EACV,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,QAAQ,EAAE,EAAE,GACX,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,iBAAiB,CAAC,EAAE,CAAC,CAAC,CAAC;CAY5D,CAAC;AAcF,eAAO,MAAM,sBAAsB,EAAE;IACnC,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EACT,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAClC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EACT,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,KAC3B,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;IACvE,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAClB,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,EAC9B,QAAQ,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAClC,MAAM,CAAC,MAAM,CAAC,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,EAAE,iBAAiB,CAAC,GAAG,EAAE,EAAE,CAAC,GAAG,EAAE,CAAC,CAAC;CAYtE,CAAC"}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { Effect } from "effect";
|
|
2
|
+
import { dual } from "effect/Function";
|
|
3
|
+
export const hasTaggedErrorShape = (error) => error !== null && typeof error === "object" && "_tag" in error && typeof error._tag === "string";
|
|
4
|
+
export const isTaggedError = (tag) => (error) => hasTaggedErrorShape(error) && error._tag === tag;
|
|
5
|
+
export const isUserRejectedError = isTaggedError("UserRejectedError");
|
|
6
|
+
export const catchUserRejection = dual(2, (effect, fallback) => Effect.catchIf(effect, isUserRejectedError, () => Effect.succeed(fallback)));
|
|
7
|
+
export const catchUserRejectionWith = dual(2, (effect, fallback) => Effect.catchIf(effect, isUserRejectedError, () => fallback));
|
|
8
|
+
//# sourceMappingURL=predicates.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"predicates.js","sourceRoot":"","sources":["../../../src/core/errors/predicates.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAC;AAChC,OAAO,EAAE,IAAI,EAAE,MAAM,iBAAiB,CAAC;AAevC,MAAM,CAAC,MAAM,mBAAmB,GAAG,CAAC,KAAc,EAA6B,EAAE,CAC/E,KAAK,KAAK,IAAI,IAAI,OAAO,KAAK,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK,IAAI,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,CAAC;AAMnG,MAAM,CAAC,MAAM,aAAa,GACxB,CAAsC,GAAc,EAAE,EAAE,CACxD,CAAC,KAAc,EAAc,EAAE,CAC7B,mBAAmB,CAAC,KAAK,CAAC,IAAI,KAAK,CAAC,IAAI,KAAK,GAAG,CAAC;AAMrD,MAAM,CAAC,MAAM,mBAAmB,GAAG,aAAa,CAAoB,mBAAmB,CAAC,CAAC;AAgBzF,MAAM,CAAC,MAAM,kBAAkB,GAU3B,IAAI,CACN,CAAC,EACD,CACE,MAA8B,EAC9B,QAAY,EAC6C,EAAE,CAC3D,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,CAIzE,CACJ,CAAC;AAcF,MAAM,CAAC,MAAM,sBAAsB,GAU/B,IAAI,CACN,CAAC,EACD,CACE,MAA8B,EAC9B,QAAmC,EACgC,EAAE,CACrE,MAAM,CAAC,OAAO,CAAC,MAAM,EAAE,mBAAmB,EAAE,GAAG,EAAE,CAAC,QAAQ,CAIzD,CACJ,CAAC"}
|