openzoo 0.3.0 → 0.3.1

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 (2) hide show
  1. package/lib/wrap.js +38 -2
  2. package/package.json +1 -1
package/lib/wrap.js CHANGED
@@ -18,7 +18,7 @@
18
18
  * authority = PDA(['mint_authority', wrappedMint]); escrow = ATA(underlying,
19
19
  * authority); registry = PDA(['backpointer', wrappedMint]) when present.
20
20
  */
21
- import { PublicKey, Transaction, TransactionInstruction, sendAndConfirmTransaction } from '@solana/web3.js';
21
+ import { PublicKey, Transaction, TransactionInstruction } from '@solana/web3.js';
22
22
  import {
23
23
  TOKEN_PROGRAM_ID,
24
24
  TOKEN_2022_PROGRAM_ID,
@@ -200,9 +200,45 @@ export function buildWrapInstructions({ pool, owner, depositRaw, rentPayer = own
200
200
  ];
201
201
  }
202
202
 
203
+ /**
204
+ * Confirm a signature by polling getSignatureStatuses over HTTP. Deliberately
205
+ * avoids connection.confirmTransaction: that path opens a websocket
206
+ * signatureSubscribe, and some RPC providers (fluxrpc) send a notification
207
+ * shape web3.js's schema rejects — the StructError fires inside the ws
208
+ * callback where no caller can catch it and takes down the whole process.
209
+ */
210
+ export async function confirmSignatureByPolling(connection, signature, {
211
+ commitment = 'confirmed',
212
+ timeoutMs = 90000,
213
+ pollMs = 1500,
214
+ } = {}) {
215
+ const accept = commitment === 'finalized' ? ['finalized'] : ['confirmed', 'finalized'];
216
+ const deadline = Date.now() + timeoutMs;
217
+ for (;;) {
218
+ let status = null;
219
+ try {
220
+ const res = await connection.getSignatureStatuses([signature]);
221
+ status = res?.value?.[0] ?? null;
222
+ } catch { /* transient RPC hiccup — keep polling until the deadline */ }
223
+ if (status) {
224
+ if (status.err) throw new Error(`transaction ${signature} failed on-chain: ${JSON.stringify(status.err)}`);
225
+ if (accept.includes(status.confirmationStatus)) return signature;
226
+ }
227
+ if (Date.now() >= deadline) {
228
+ throw new Error(`timed out after ${timeoutMs}ms waiting for confirmation of ${signature}`);
229
+ }
230
+ await new Promise((resolve) => setTimeout(resolve, pollMs));
231
+ }
232
+ }
233
+
203
234
  /** Send a self-paid conversion tx and wait for confirmation. Returns the signature. */
204
235
  export async function sendWrap(connection, keypair, pool, depositRaw) {
205
236
  const ixs = buildWrapInstructions({ pool, owner: keypair.publicKey, depositRaw });
206
237
  const tx = new Transaction().add(...ixs);
207
- return sendAndConfirmTransaction(connection, tx, [keypair], { commitment: 'confirmed' });
238
+ const { blockhash } = await connection.getLatestBlockhash('confirmed');
239
+ tx.recentBlockhash = blockhash;
240
+ tx.feePayer = keypair.publicKey;
241
+ tx.sign(keypair);
242
+ const sig = await connection.sendRawTransaction(tx.serialize());
243
+ return confirmSignatureByPolling(connection, sig, { commitment: 'confirmed' });
208
244
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "openzoo",
3
- "version": "0.3.0",
3
+ "version": "0.3.1",
4
4
  "description": "Local x402-paying proxy + MCP server for openzoo.fun — point any OpenAI-compatible harness (Cursor, Claude Code, aider, SDKs) at localhost and it pays per call from a local burner wallet. Solana rail live; Base/Robinhood rails experimental.",
5
5
  "license": "MIT",
6
6
  "type": "module",