@caatinga/client 0.2.4 → 2.0.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/dist/index.cjs +227 -189
- package/dist/index.d.cts +0 -1
- package/dist/index.d.ts +0 -1
- package/dist/index.js +227 -189
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -38,12 +38,38 @@ function resolveContractId(input) {
|
|
|
38
38
|
if (contractId) {
|
|
39
39
|
return contractId;
|
|
40
40
|
}
|
|
41
|
+
const hint = formatMissingContractArtifactHint(input.artifacts, input.network, input.contract);
|
|
41
42
|
throw new import_browser.CaatingaError(
|
|
42
43
|
`No contract artifact found for "${input.contract}" on "${input.network}".`,
|
|
43
44
|
import_browser.CaatingaErrorCode.CONTRACT_ARTIFACT_NOT_FOUND,
|
|
44
|
-
|
|
45
|
+
hint
|
|
45
46
|
);
|
|
46
47
|
}
|
|
48
|
+
function formatMissingContractArtifactHint(artifacts, network, contract) {
|
|
49
|
+
const deployCommand = `caatinga deploy ${contract} --network ${network} --source <identity>`;
|
|
50
|
+
const buildNote = "caatinga build does not register a contract ID.";
|
|
51
|
+
if (Object.keys(artifacts.networks).length === 0) {
|
|
52
|
+
return [
|
|
53
|
+
"caatinga.artifacts.json has no network scaffold.",
|
|
54
|
+
`Run caatinga doctor --network ${network} to inspect deploy readiness, then run: ${deployCommand}.`,
|
|
55
|
+
buildNote,
|
|
56
|
+
"Or pass contractId in the client registration."
|
|
57
|
+
].join(" ");
|
|
58
|
+
}
|
|
59
|
+
if (!artifacts.networks[network]) {
|
|
60
|
+
return [
|
|
61
|
+
`No artifacts exist for network "${network}".`,
|
|
62
|
+
`Run: ${deployCommand}.`,
|
|
63
|
+
buildNote,
|
|
64
|
+
"Or pass contractId in the client registration."
|
|
65
|
+
].join(" ");
|
|
66
|
+
}
|
|
67
|
+
return [
|
|
68
|
+
`Contract "${contract}" is not deployed on "${network}".`,
|
|
69
|
+
`Run: ${deployCommand}.`,
|
|
70
|
+
"Or pass contractId in the client registration."
|
|
71
|
+
].join(" ");
|
|
72
|
+
}
|
|
47
73
|
|
|
48
74
|
// src/bindings/default-binding-adapter.ts
|
|
49
75
|
var import_browser2 = require("@caatinga/core/browser");
|
|
@@ -80,10 +106,10 @@ function createDefaultBindingAdapter(binding) {
|
|
|
80
106
|
}
|
|
81
107
|
|
|
82
108
|
// src/client/create-caatinga-client.ts
|
|
83
|
-
var
|
|
109
|
+
var import_browser8 = require("@caatinga/core/browser");
|
|
84
110
|
|
|
85
111
|
// src/client/caatinga-contract-client.ts
|
|
86
|
-
var
|
|
112
|
+
var import_browser7 = require("@caatinga/core/browser");
|
|
87
113
|
|
|
88
114
|
// src/xdr/build-xdr.ts
|
|
89
115
|
var import_browser3 = require("@caatinga/core/browser");
|
|
@@ -142,6 +168,188 @@ function readXdr(transaction) {
|
|
|
142
168
|
return candidate.toXDR();
|
|
143
169
|
}
|
|
144
170
|
|
|
171
|
+
// src/wallet/with-wallet-timeout.ts
|
|
172
|
+
var import_browser4 = require("@caatinga/core/browser");
|
|
173
|
+
function withWalletTimeout(label, timeoutMs, fn) {
|
|
174
|
+
if (timeoutMs === void 0 || timeoutMs <= 0) {
|
|
175
|
+
return fn();
|
|
176
|
+
}
|
|
177
|
+
let timedOut = false;
|
|
178
|
+
return new Promise((resolve, reject) => {
|
|
179
|
+
const timer = setTimeout(() => {
|
|
180
|
+
timedOut = true;
|
|
181
|
+
reject(
|
|
182
|
+
new import_browser4.CaatingaError(
|
|
183
|
+
`Wallet "${label}" timed out after ${timeoutMs}ms.`,
|
|
184
|
+
import_browser4.CaatingaErrorCode.WALLET_TIMEOUT,
|
|
185
|
+
"Ensure the wallet adapter rejects on user dismissal, or increase walletTimeout."
|
|
186
|
+
)
|
|
187
|
+
);
|
|
188
|
+
}, timeoutMs);
|
|
189
|
+
fn().then(
|
|
190
|
+
(value) => {
|
|
191
|
+
if (timedOut) {
|
|
192
|
+
return;
|
|
193
|
+
}
|
|
194
|
+
clearTimeout(timer);
|
|
195
|
+
resolve(value);
|
|
196
|
+
},
|
|
197
|
+
(error) => {
|
|
198
|
+
if (timedOut) {
|
|
199
|
+
return;
|
|
200
|
+
}
|
|
201
|
+
clearTimeout(timer);
|
|
202
|
+
reject(error);
|
|
203
|
+
}
|
|
204
|
+
);
|
|
205
|
+
});
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
// src/client/invoke-args.ts
|
|
209
|
+
function splitArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
210
|
+
return {
|
|
211
|
+
args: argsOrOptions,
|
|
212
|
+
debugRaw: maybeOptions?.debugRaw ?? false
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
function splitInvokeArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
216
|
+
const looksLikeOptions = argsOrOptions !== void 0 && ("debugXdr" in argsOrOptions || "debugRaw" in argsOrOptions) && maybeOptions === void 0;
|
|
217
|
+
if (looksLikeOptions) {
|
|
218
|
+
const options = argsOrOptions;
|
|
219
|
+
return {
|
|
220
|
+
args: void 0,
|
|
221
|
+
debugXdr: options.debugXdr ?? false,
|
|
222
|
+
debugRaw: options.debugRaw ?? false
|
|
223
|
+
};
|
|
224
|
+
}
|
|
225
|
+
return {
|
|
226
|
+
args: argsOrOptions,
|
|
227
|
+
debugXdr: maybeOptions?.debugXdr ?? false,
|
|
228
|
+
debugRaw: maybeOptions?.debugRaw ?? false
|
|
229
|
+
};
|
|
230
|
+
}
|
|
231
|
+
function splitReadArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
232
|
+
const looksLikeOptions = argsOrOptions !== void 0 && "debugRaw" in argsOrOptions && maybeOptions === void 0;
|
|
233
|
+
if (looksLikeOptions) {
|
|
234
|
+
const options = argsOrOptions;
|
|
235
|
+
return {
|
|
236
|
+
args: void 0,
|
|
237
|
+
debugRaw: options.debugRaw ?? false
|
|
238
|
+
};
|
|
239
|
+
}
|
|
240
|
+
return {
|
|
241
|
+
args: argsOrOptions,
|
|
242
|
+
debugRaw: maybeOptions?.debugRaw ?? false
|
|
243
|
+
};
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
// src/client/transaction-simulate.ts
|
|
247
|
+
var import_browser5 = require("@caatinga/core/browser");
|
|
248
|
+
async function prepareReadTransaction(transaction, contractName, method, rpcUrl) {
|
|
249
|
+
const candidate = transaction;
|
|
250
|
+
if (typeof candidate.prepare !== "function") {
|
|
251
|
+
return transaction;
|
|
252
|
+
}
|
|
253
|
+
try {
|
|
254
|
+
return await candidate.prepare.call(transaction);
|
|
255
|
+
} catch (error) {
|
|
256
|
+
if (error instanceof import_browser5.CaatingaError) {
|
|
257
|
+
throw error;
|
|
258
|
+
}
|
|
259
|
+
throw new import_browser5.CaatingaError(
|
|
260
|
+
`Failed to prepare XDR for "${contractName}.${method}".`,
|
|
261
|
+
import_browser5.CaatingaErrorCode.XDR_PREPARE_FAILED,
|
|
262
|
+
`RPC: ${rpcUrl}. Check connectivity, simulation errors, and binding compatibility.`,
|
|
263
|
+
error
|
|
264
|
+
);
|
|
265
|
+
}
|
|
266
|
+
}
|
|
267
|
+
function readSimulationResult(raw, contractName, method) {
|
|
268
|
+
if (raw !== null && typeof raw === "object" && "result" in raw) {
|
|
269
|
+
const result = raw.result;
|
|
270
|
+
if (result !== void 0) {
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
throw new import_browser5.CaatingaError(
|
|
275
|
+
`Simulation for "${contractName}.${method}" did not return a result.`,
|
|
276
|
+
import_browser5.CaatingaErrorCode.READ_RESULT_MISSING,
|
|
277
|
+
`Expected "${contractName}.${method}" to expose a simulation result. Use debugRaw to inspect the generated binding output.`
|
|
278
|
+
);
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
// src/client/transaction-submit.ts
|
|
282
|
+
var import_browser6 = require("@caatinga/core/browser");
|
|
283
|
+
async function submitTransaction(transaction, signTransaction, contractName, method, rpcUrl) {
|
|
284
|
+
const candidate = transaction;
|
|
285
|
+
if (typeof candidate.signAndSend === "function") {
|
|
286
|
+
try {
|
|
287
|
+
const raw = await candidate.signAndSend.call(transaction, { signTransaction });
|
|
288
|
+
assertSubmitResultRecognized(raw, contractName, method);
|
|
289
|
+
return raw;
|
|
290
|
+
} catch (error) {
|
|
291
|
+
if (error instanceof import_browser6.CaatingaError) {
|
|
292
|
+
throw error;
|
|
293
|
+
}
|
|
294
|
+
throw new import_browser6.CaatingaError(
|
|
295
|
+
`Failed to submit XDR for "${contractName}.${method}".`,
|
|
296
|
+
import_browser6.CaatingaErrorCode.XDR_SUBMIT_FAILED,
|
|
297
|
+
`RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
|
|
298
|
+
error
|
|
299
|
+
);
|
|
300
|
+
}
|
|
301
|
+
}
|
|
302
|
+
if (typeof candidate.send === "function") {
|
|
303
|
+
try {
|
|
304
|
+
const raw = await candidate.send.call(transaction);
|
|
305
|
+
assertSubmitResultRecognized(raw, contractName, method);
|
|
306
|
+
return raw;
|
|
307
|
+
} catch (error) {
|
|
308
|
+
if (error instanceof import_browser6.CaatingaError) {
|
|
309
|
+
throw error;
|
|
310
|
+
}
|
|
311
|
+
throw new import_browser6.CaatingaError(
|
|
312
|
+
`Failed to submit XDR for "${contractName}.${method}".`,
|
|
313
|
+
import_browser6.CaatingaErrorCode.XDR_SUBMIT_FAILED,
|
|
314
|
+
`RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
|
|
315
|
+
error
|
|
316
|
+
);
|
|
317
|
+
}
|
|
318
|
+
}
|
|
319
|
+
throw new import_browser6.CaatingaError(
|
|
320
|
+
`Binding transaction for "${contractName}.${method}" cannot be submitted.`,
|
|
321
|
+
import_browser6.CaatingaErrorCode.XDR_SUBMIT_FAILED,
|
|
322
|
+
"Regenerate bindings or provide a compatible binding adapter."
|
|
323
|
+
);
|
|
324
|
+
}
|
|
325
|
+
function assertSubmitResultRecognized(raw, contractName, method) {
|
|
326
|
+
if (raw === null || typeof raw !== "object") {
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
const record = raw;
|
|
330
|
+
const hasTransactionId = "txHash" in record || "transactionHash" in record || "hash" in record || hasNestedSendTransactionResponseHash(record);
|
|
331
|
+
const hasResult = "result" in record;
|
|
332
|
+
if (hasTransactionId || hasResult) {
|
|
333
|
+
return;
|
|
334
|
+
}
|
|
335
|
+
throw new import_browser6.CaatingaError(
|
|
336
|
+
`Submit returned an unrecognized payload for "${contractName}.${method}".`,
|
|
337
|
+
import_browser6.CaatingaErrorCode.XDR_RESULT_FAILED,
|
|
338
|
+
"Expected txHash, transactionHash, hash, sendTransactionResponse.hash, or result on the submit response. Use debugRaw to inspect the binding output."
|
|
339
|
+
);
|
|
340
|
+
}
|
|
341
|
+
function hasNestedSendTransactionResponseHash(record) {
|
|
342
|
+
const response = record.sendTransactionResponse;
|
|
343
|
+
return response !== null && typeof response === "object" && "hash" in response;
|
|
344
|
+
}
|
|
345
|
+
function normalizeSubmitResult(raw) {
|
|
346
|
+
const candidate = raw;
|
|
347
|
+
return {
|
|
348
|
+
transactionHash: candidate.txHash ?? candidate.transactionHash ?? candidate.hash ?? candidate.sendTransactionResponse?.hash,
|
|
349
|
+
result: candidate.result
|
|
350
|
+
};
|
|
351
|
+
}
|
|
352
|
+
|
|
145
353
|
// src/client/caatinga-contract-client.ts
|
|
146
354
|
var CaatingaContractClient = class {
|
|
147
355
|
constructor(config, contractName, registration, bindingAdapter = createDefaultBindingAdapter(
|
|
@@ -182,28 +390,29 @@ var CaatingaContractClient = class {
|
|
|
182
390
|
let signedXdr;
|
|
183
391
|
const signTransaction = async (xdr2) => {
|
|
184
392
|
try {
|
|
185
|
-
signedXdr = await
|
|
393
|
+
signedXdr = await withWalletTimeout(
|
|
186
394
|
"signTransaction",
|
|
395
|
+
this.config.walletTimeout,
|
|
187
396
|
() => this.config.wallet.signTransaction({
|
|
188
397
|
xdr: xdr2,
|
|
189
398
|
networkPassphrase: this.config.network.networkPassphrase
|
|
190
399
|
})
|
|
191
400
|
);
|
|
192
401
|
} catch (error) {
|
|
193
|
-
if (error instanceof
|
|
402
|
+
if (error instanceof import_browser7.CaatingaError) {
|
|
194
403
|
throw error;
|
|
195
404
|
}
|
|
196
|
-
throw new
|
|
405
|
+
throw new import_browser7.CaatingaError(
|
|
197
406
|
`Failed to sign XDR for "${this.contractName}.${method}".`,
|
|
198
|
-
|
|
407
|
+
import_browser7.CaatingaErrorCode.XDR_SIGN_FAILED,
|
|
199
408
|
"Connect a wallet and approve the transaction.",
|
|
200
409
|
error
|
|
201
410
|
);
|
|
202
411
|
}
|
|
203
412
|
if (typeof signedXdr !== "string" || signedXdr.trim().length === 0) {
|
|
204
|
-
throw new
|
|
413
|
+
throw new import_browser7.CaatingaError(
|
|
205
414
|
`Failed to sign XDR for "${this.contractName}.${method}".`,
|
|
206
|
-
|
|
415
|
+
import_browser7.CaatingaErrorCode.XDR_SIGN_FAILED,
|
|
207
416
|
"Wallet returned an empty or invalid signed XDR. The user may have dismissed the signing prompt.",
|
|
208
417
|
signedXdr
|
|
209
418
|
);
|
|
@@ -218,9 +427,9 @@ var CaatingaContractClient = class {
|
|
|
218
427
|
this.config.network.rpcUrl
|
|
219
428
|
);
|
|
220
429
|
if (typeof transaction.signAndSend === "function" && signedXdr === void 0) {
|
|
221
|
-
throw new
|
|
430
|
+
throw new import_browser7.CaatingaError(
|
|
222
431
|
`Failed to sign XDR for "${this.contractName}.${method}".`,
|
|
223
|
-
|
|
432
|
+
import_browser7.CaatingaErrorCode.XDR_SIGN_FAILED,
|
|
224
433
|
"Wallet returned an empty or invalid signed XDR. The generated transaction did not request a wallet signature."
|
|
225
434
|
);
|
|
226
435
|
}
|
|
@@ -274,17 +483,18 @@ var CaatingaContractClient = class {
|
|
|
274
483
|
});
|
|
275
484
|
let publicKey;
|
|
276
485
|
try {
|
|
277
|
-
publicKey = await
|
|
486
|
+
publicKey = await withWalletTimeout(
|
|
278
487
|
"getPublicKey",
|
|
488
|
+
this.config.walletTimeout,
|
|
279
489
|
() => this.config.wallet.getPublicKey()
|
|
280
490
|
);
|
|
281
491
|
} catch (error) {
|
|
282
|
-
if (error instanceof
|
|
492
|
+
if (error instanceof import_browser7.CaatingaError) {
|
|
283
493
|
throw error;
|
|
284
494
|
}
|
|
285
|
-
throw new
|
|
495
|
+
throw new import_browser7.CaatingaError(
|
|
286
496
|
`Wallet is not connected or the public key is unavailable for "${this.contractName}".`,
|
|
287
|
-
|
|
497
|
+
import_browser7.CaatingaErrorCode.WALLET_NOT_CONNECTED,
|
|
288
498
|
"Connect the wallet and grant account access, then retry.",
|
|
289
499
|
error
|
|
290
500
|
);
|
|
@@ -298,179 +508,7 @@ var CaatingaContractClient = class {
|
|
|
298
508
|
const transaction = await this.bindingAdapter.callMethod({ client, method, args });
|
|
299
509
|
return { contractId, transaction };
|
|
300
510
|
}
|
|
301
|
-
withWalletTimeout(label, fn) {
|
|
302
|
-
const timeoutMs = this.config.walletTimeout;
|
|
303
|
-
if (timeoutMs === void 0 || timeoutMs <= 0) {
|
|
304
|
-
return fn();
|
|
305
|
-
}
|
|
306
|
-
let timedOut = false;
|
|
307
|
-
return new Promise((resolve, reject) => {
|
|
308
|
-
const timer = setTimeout(() => {
|
|
309
|
-
timedOut = true;
|
|
310
|
-
reject(
|
|
311
|
-
new import_browser4.CaatingaError(
|
|
312
|
-
`Wallet "${label}" timed out after ${timeoutMs}ms.`,
|
|
313
|
-
import_browser4.CaatingaErrorCode.WALLET_TIMEOUT,
|
|
314
|
-
"Ensure the wallet adapter rejects on user dismissal, or increase walletTimeout."
|
|
315
|
-
)
|
|
316
|
-
);
|
|
317
|
-
}, timeoutMs);
|
|
318
|
-
fn().then(
|
|
319
|
-
(value) => {
|
|
320
|
-
if (timedOut) {
|
|
321
|
-
return;
|
|
322
|
-
}
|
|
323
|
-
clearTimeout(timer);
|
|
324
|
-
resolve(value);
|
|
325
|
-
},
|
|
326
|
-
(error) => {
|
|
327
|
-
if (timedOut) {
|
|
328
|
-
return;
|
|
329
|
-
}
|
|
330
|
-
clearTimeout(timer);
|
|
331
|
-
reject(error);
|
|
332
|
-
}
|
|
333
|
-
);
|
|
334
|
-
});
|
|
335
|
-
}
|
|
336
511
|
};
|
|
337
|
-
function splitArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
338
|
-
return {
|
|
339
|
-
args: argsOrOptions,
|
|
340
|
-
debugRaw: maybeOptions?.debugRaw ?? false
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
function splitInvokeArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
344
|
-
const looksLikeOptions = argsOrOptions !== void 0 && ("debugXdr" in argsOrOptions || "debugRaw" in argsOrOptions) && maybeOptions === void 0;
|
|
345
|
-
if (looksLikeOptions) {
|
|
346
|
-
const options = argsOrOptions;
|
|
347
|
-
return {
|
|
348
|
-
args: void 0,
|
|
349
|
-
debugXdr: options.debugXdr ?? false,
|
|
350
|
-
debugRaw: options.debugRaw ?? false
|
|
351
|
-
};
|
|
352
|
-
}
|
|
353
|
-
return {
|
|
354
|
-
args: argsOrOptions,
|
|
355
|
-
debugXdr: maybeOptions?.debugXdr ?? false,
|
|
356
|
-
debugRaw: maybeOptions?.debugRaw ?? false
|
|
357
|
-
};
|
|
358
|
-
}
|
|
359
|
-
function splitReadArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
360
|
-
const looksLikeOptions = argsOrOptions !== void 0 && "debugRaw" in argsOrOptions && maybeOptions === void 0;
|
|
361
|
-
if (looksLikeOptions) {
|
|
362
|
-
const options = argsOrOptions;
|
|
363
|
-
return {
|
|
364
|
-
args: void 0,
|
|
365
|
-
debugRaw: options.debugRaw ?? false
|
|
366
|
-
};
|
|
367
|
-
}
|
|
368
|
-
return {
|
|
369
|
-
args: argsOrOptions,
|
|
370
|
-
debugRaw: maybeOptions?.debugRaw ?? false
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
async function submitTransaction(transaction, signTransaction, contractName, method, rpcUrl) {
|
|
374
|
-
const candidate = transaction;
|
|
375
|
-
if (typeof candidate.signAndSend === "function") {
|
|
376
|
-
try {
|
|
377
|
-
const raw = await candidate.signAndSend.call(transaction, { signTransaction });
|
|
378
|
-
assertSubmitResultRecognized(raw, contractName, method);
|
|
379
|
-
return raw;
|
|
380
|
-
} catch (error) {
|
|
381
|
-
if (error instanceof import_browser4.CaatingaError) {
|
|
382
|
-
throw error;
|
|
383
|
-
}
|
|
384
|
-
throw new import_browser4.CaatingaError(
|
|
385
|
-
`Failed to submit XDR for "${contractName}.${method}".`,
|
|
386
|
-
import_browser4.CaatingaErrorCode.XDR_SUBMIT_FAILED,
|
|
387
|
-
`RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
|
|
388
|
-
error
|
|
389
|
-
);
|
|
390
|
-
}
|
|
391
|
-
}
|
|
392
|
-
if (typeof candidate.send === "function") {
|
|
393
|
-
try {
|
|
394
|
-
const raw = await candidate.send.call(transaction);
|
|
395
|
-
assertSubmitResultRecognized(raw, contractName, method);
|
|
396
|
-
return raw;
|
|
397
|
-
} catch (error) {
|
|
398
|
-
if (error instanceof import_browser4.CaatingaError) {
|
|
399
|
-
throw error;
|
|
400
|
-
}
|
|
401
|
-
throw new import_browser4.CaatingaError(
|
|
402
|
-
`Failed to submit XDR for "${contractName}.${method}".`,
|
|
403
|
-
import_browser4.CaatingaErrorCode.XDR_SUBMIT_FAILED,
|
|
404
|
-
`RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
|
|
405
|
-
error
|
|
406
|
-
);
|
|
407
|
-
}
|
|
408
|
-
}
|
|
409
|
-
throw new import_browser4.CaatingaError(
|
|
410
|
-
`Binding transaction for "${contractName}.${method}" cannot be submitted.`,
|
|
411
|
-
import_browser4.CaatingaErrorCode.XDR_SUBMIT_FAILED,
|
|
412
|
-
"Regenerate bindings or provide a compatible binding adapter."
|
|
413
|
-
);
|
|
414
|
-
}
|
|
415
|
-
async function prepareReadTransaction(transaction, contractName, method, rpcUrl) {
|
|
416
|
-
const candidate = transaction;
|
|
417
|
-
if (typeof candidate.prepare !== "function") {
|
|
418
|
-
return transaction;
|
|
419
|
-
}
|
|
420
|
-
try {
|
|
421
|
-
return await candidate.prepare.call(transaction);
|
|
422
|
-
} catch (error) {
|
|
423
|
-
if (error instanceof import_browser4.CaatingaError) {
|
|
424
|
-
throw error;
|
|
425
|
-
}
|
|
426
|
-
throw new import_browser4.CaatingaError(
|
|
427
|
-
`Failed to prepare XDR for "${contractName}.${method}".`,
|
|
428
|
-
import_browser4.CaatingaErrorCode.XDR_PREPARE_FAILED,
|
|
429
|
-
`RPC: ${rpcUrl}. Check connectivity, simulation errors, and binding compatibility.`,
|
|
430
|
-
error
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
}
|
|
434
|
-
function readSimulationResult(raw, contractName, method) {
|
|
435
|
-
if (raw !== null && typeof raw === "object" && "result" in raw) {
|
|
436
|
-
const result = raw.result;
|
|
437
|
-
if (result !== void 0) {
|
|
438
|
-
return result;
|
|
439
|
-
}
|
|
440
|
-
}
|
|
441
|
-
throw new import_browser4.CaatingaError(
|
|
442
|
-
`Simulation for "${contractName}.${method}" did not return a result.`,
|
|
443
|
-
import_browser4.CaatingaErrorCode.READ_RESULT_MISSING,
|
|
444
|
-
`Expected "${contractName}.${method}" to expose a simulation result. Use debugRaw to inspect the generated binding output.`
|
|
445
|
-
);
|
|
446
|
-
}
|
|
447
|
-
function assertSubmitResultRecognized(raw, contractName, method) {
|
|
448
|
-
if (raw === null || typeof raw !== "object") {
|
|
449
|
-
return;
|
|
450
|
-
}
|
|
451
|
-
const record = raw;
|
|
452
|
-
const hasTransactionId = "txHash" in record || "transactionHash" in record || "hash" in record || hasNestedSendTransactionResponseHash(record);
|
|
453
|
-
const hasResult = "result" in record;
|
|
454
|
-
if (hasTransactionId || hasResult) {
|
|
455
|
-
return;
|
|
456
|
-
}
|
|
457
|
-
throw new import_browser4.CaatingaError(
|
|
458
|
-
`Submit returned an unrecognized payload for "${contractName}.${method}".`,
|
|
459
|
-
import_browser4.CaatingaErrorCode.XDR_RESULT_FAILED,
|
|
460
|
-
"Expected txHash, transactionHash, hash, sendTransactionResponse.hash, or result on the submit response. Use debugRaw to inspect the binding output."
|
|
461
|
-
);
|
|
462
|
-
}
|
|
463
|
-
function hasNestedSendTransactionResponseHash(record) {
|
|
464
|
-
const response = record.sendTransactionResponse;
|
|
465
|
-
return response !== null && typeof response === "object" && "hash" in response;
|
|
466
|
-
}
|
|
467
|
-
function normalizeSubmitResult(raw) {
|
|
468
|
-
const candidate = raw;
|
|
469
|
-
return {
|
|
470
|
-
transactionHash: candidate.txHash ?? candidate.transactionHash ?? candidate.hash ?? candidate.sendTransactionResponse?.hash,
|
|
471
|
-
result: candidate.result
|
|
472
|
-
};
|
|
473
|
-
}
|
|
474
512
|
|
|
475
513
|
// src/client/create-caatinga-client.ts
|
|
476
514
|
function createCaatingaClient(config) {
|
|
@@ -478,9 +516,9 @@ function createCaatingaClient(config) {
|
|
|
478
516
|
contract(contractName) {
|
|
479
517
|
const registration = config.contracts[contractName];
|
|
480
518
|
if (!registration) {
|
|
481
|
-
throw new
|
|
519
|
+
throw new import_browser8.CaatingaError(
|
|
482
520
|
`Contract "${contractName}" is not registered.`,
|
|
483
|
-
|
|
521
|
+
import_browser8.CaatingaErrorCode.CONTRACT_NOT_FOUND,
|
|
484
522
|
"Add the contract binding to createCaatingaClient()."
|
|
485
523
|
);
|
|
486
524
|
}
|
package/dist/index.d.cts
CHANGED
|
@@ -32,7 +32,6 @@ declare class CaatingaContractClient {
|
|
|
32
32
|
simulate<T = unknown>(method: string, argsOrOptions?: Record<string, unknown> | CaatingaReadOptions, maybeOptions?: CaatingaReadOptions): Promise<CaatingaReadResult<T>>;
|
|
33
33
|
read<T = unknown>(method: string, argsOrOptions?: Record<string, unknown> | CaatingaReadOptions, maybeOptions?: CaatingaReadOptions): Promise<T>;
|
|
34
34
|
private createTransaction;
|
|
35
|
-
private withWalletTimeout;
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
declare function createCaatingaClient(config: CaatingaClientConfig): {
|
package/dist/index.d.ts
CHANGED
|
@@ -32,7 +32,6 @@ declare class CaatingaContractClient {
|
|
|
32
32
|
simulate<T = unknown>(method: string, argsOrOptions?: Record<string, unknown> | CaatingaReadOptions, maybeOptions?: CaatingaReadOptions): Promise<CaatingaReadResult<T>>;
|
|
33
33
|
read<T = unknown>(method: string, argsOrOptions?: Record<string, unknown> | CaatingaReadOptions, maybeOptions?: CaatingaReadOptions): Promise<T>;
|
|
34
34
|
private createTransaction;
|
|
35
|
-
private withWalletTimeout;
|
|
36
35
|
}
|
|
37
36
|
|
|
38
37
|
declare function createCaatingaClient(config: CaatingaClientConfig): {
|
package/dist/index.js
CHANGED
|
@@ -8,12 +8,38 @@ function resolveContractId(input) {
|
|
|
8
8
|
if (contractId) {
|
|
9
9
|
return contractId;
|
|
10
10
|
}
|
|
11
|
+
const hint = formatMissingContractArtifactHint(input.artifacts, input.network, input.contract);
|
|
11
12
|
throw new CaatingaError(
|
|
12
13
|
`No contract artifact found for "${input.contract}" on "${input.network}".`,
|
|
13
14
|
CaatingaErrorCode.CONTRACT_ARTIFACT_NOT_FOUND,
|
|
14
|
-
|
|
15
|
+
hint
|
|
15
16
|
);
|
|
16
17
|
}
|
|
18
|
+
function formatMissingContractArtifactHint(artifacts, network, contract) {
|
|
19
|
+
const deployCommand = `caatinga deploy ${contract} --network ${network} --source <identity>`;
|
|
20
|
+
const buildNote = "caatinga build does not register a contract ID.";
|
|
21
|
+
if (Object.keys(artifacts.networks).length === 0) {
|
|
22
|
+
return [
|
|
23
|
+
"caatinga.artifacts.json has no network scaffold.",
|
|
24
|
+
`Run caatinga doctor --network ${network} to inspect deploy readiness, then run: ${deployCommand}.`,
|
|
25
|
+
buildNote,
|
|
26
|
+
"Or pass contractId in the client registration."
|
|
27
|
+
].join(" ");
|
|
28
|
+
}
|
|
29
|
+
if (!artifacts.networks[network]) {
|
|
30
|
+
return [
|
|
31
|
+
`No artifacts exist for network "${network}".`,
|
|
32
|
+
`Run: ${deployCommand}.`,
|
|
33
|
+
buildNote,
|
|
34
|
+
"Or pass contractId in the client registration."
|
|
35
|
+
].join(" ");
|
|
36
|
+
}
|
|
37
|
+
return [
|
|
38
|
+
`Contract "${contract}" is not deployed on "${network}".`,
|
|
39
|
+
`Run: ${deployCommand}.`,
|
|
40
|
+
"Or pass contractId in the client registration."
|
|
41
|
+
].join(" ");
|
|
42
|
+
}
|
|
17
43
|
|
|
18
44
|
// src/bindings/default-binding-adapter.ts
|
|
19
45
|
import { CaatingaError as CaatingaError2, CaatingaErrorCode as CaatingaErrorCode2 } from "@caatinga/core/browser";
|
|
@@ -50,10 +76,10 @@ function createDefaultBindingAdapter(binding) {
|
|
|
50
76
|
}
|
|
51
77
|
|
|
52
78
|
// src/client/create-caatinga-client.ts
|
|
53
|
-
import { CaatingaError as
|
|
79
|
+
import { CaatingaError as CaatingaError8, CaatingaErrorCode as CaatingaErrorCode8 } from "@caatinga/core/browser";
|
|
54
80
|
|
|
55
81
|
// src/client/caatinga-contract-client.ts
|
|
56
|
-
import { CaatingaError as
|
|
82
|
+
import { CaatingaError as CaatingaError7, CaatingaErrorCode as CaatingaErrorCode7 } from "@caatinga/core/browser";
|
|
57
83
|
|
|
58
84
|
// src/xdr/build-xdr.ts
|
|
59
85
|
import { CaatingaError as CaatingaError3, CaatingaErrorCode as CaatingaErrorCode3 } from "@caatinga/core/browser";
|
|
@@ -112,6 +138,188 @@ function readXdr(transaction) {
|
|
|
112
138
|
return candidate.toXDR();
|
|
113
139
|
}
|
|
114
140
|
|
|
141
|
+
// src/wallet/with-wallet-timeout.ts
|
|
142
|
+
import { CaatingaError as CaatingaError4, CaatingaErrorCode as CaatingaErrorCode4 } from "@caatinga/core/browser";
|
|
143
|
+
function withWalletTimeout(label, timeoutMs, fn) {
|
|
144
|
+
if (timeoutMs === void 0 || timeoutMs <= 0) {
|
|
145
|
+
return fn();
|
|
146
|
+
}
|
|
147
|
+
let timedOut = false;
|
|
148
|
+
return new Promise((resolve, reject) => {
|
|
149
|
+
const timer = setTimeout(() => {
|
|
150
|
+
timedOut = true;
|
|
151
|
+
reject(
|
|
152
|
+
new CaatingaError4(
|
|
153
|
+
`Wallet "${label}" timed out after ${timeoutMs}ms.`,
|
|
154
|
+
CaatingaErrorCode4.WALLET_TIMEOUT,
|
|
155
|
+
"Ensure the wallet adapter rejects on user dismissal, or increase walletTimeout."
|
|
156
|
+
)
|
|
157
|
+
);
|
|
158
|
+
}, timeoutMs);
|
|
159
|
+
fn().then(
|
|
160
|
+
(value) => {
|
|
161
|
+
if (timedOut) {
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
clearTimeout(timer);
|
|
165
|
+
resolve(value);
|
|
166
|
+
},
|
|
167
|
+
(error) => {
|
|
168
|
+
if (timedOut) {
|
|
169
|
+
return;
|
|
170
|
+
}
|
|
171
|
+
clearTimeout(timer);
|
|
172
|
+
reject(error);
|
|
173
|
+
}
|
|
174
|
+
);
|
|
175
|
+
});
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
// src/client/invoke-args.ts
|
|
179
|
+
function splitArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
180
|
+
return {
|
|
181
|
+
args: argsOrOptions,
|
|
182
|
+
debugRaw: maybeOptions?.debugRaw ?? false
|
|
183
|
+
};
|
|
184
|
+
}
|
|
185
|
+
function splitInvokeArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
186
|
+
const looksLikeOptions = argsOrOptions !== void 0 && ("debugXdr" in argsOrOptions || "debugRaw" in argsOrOptions) && maybeOptions === void 0;
|
|
187
|
+
if (looksLikeOptions) {
|
|
188
|
+
const options = argsOrOptions;
|
|
189
|
+
return {
|
|
190
|
+
args: void 0,
|
|
191
|
+
debugXdr: options.debugXdr ?? false,
|
|
192
|
+
debugRaw: options.debugRaw ?? false
|
|
193
|
+
};
|
|
194
|
+
}
|
|
195
|
+
return {
|
|
196
|
+
args: argsOrOptions,
|
|
197
|
+
debugXdr: maybeOptions?.debugXdr ?? false,
|
|
198
|
+
debugRaw: maybeOptions?.debugRaw ?? false
|
|
199
|
+
};
|
|
200
|
+
}
|
|
201
|
+
function splitReadArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
202
|
+
const looksLikeOptions = argsOrOptions !== void 0 && "debugRaw" in argsOrOptions && maybeOptions === void 0;
|
|
203
|
+
if (looksLikeOptions) {
|
|
204
|
+
const options = argsOrOptions;
|
|
205
|
+
return {
|
|
206
|
+
args: void 0,
|
|
207
|
+
debugRaw: options.debugRaw ?? false
|
|
208
|
+
};
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
args: argsOrOptions,
|
|
212
|
+
debugRaw: maybeOptions?.debugRaw ?? false
|
|
213
|
+
};
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
// src/client/transaction-simulate.ts
|
|
217
|
+
import { CaatingaError as CaatingaError5, CaatingaErrorCode as CaatingaErrorCode5 } from "@caatinga/core/browser";
|
|
218
|
+
async function prepareReadTransaction(transaction, contractName, method, rpcUrl) {
|
|
219
|
+
const candidate = transaction;
|
|
220
|
+
if (typeof candidate.prepare !== "function") {
|
|
221
|
+
return transaction;
|
|
222
|
+
}
|
|
223
|
+
try {
|
|
224
|
+
return await candidate.prepare.call(transaction);
|
|
225
|
+
} catch (error) {
|
|
226
|
+
if (error instanceof CaatingaError5) {
|
|
227
|
+
throw error;
|
|
228
|
+
}
|
|
229
|
+
throw new CaatingaError5(
|
|
230
|
+
`Failed to prepare XDR for "${contractName}.${method}".`,
|
|
231
|
+
CaatingaErrorCode5.XDR_PREPARE_FAILED,
|
|
232
|
+
`RPC: ${rpcUrl}. Check connectivity, simulation errors, and binding compatibility.`,
|
|
233
|
+
error
|
|
234
|
+
);
|
|
235
|
+
}
|
|
236
|
+
}
|
|
237
|
+
function readSimulationResult(raw, contractName, method) {
|
|
238
|
+
if (raw !== null && typeof raw === "object" && "result" in raw) {
|
|
239
|
+
const result = raw.result;
|
|
240
|
+
if (result !== void 0) {
|
|
241
|
+
return result;
|
|
242
|
+
}
|
|
243
|
+
}
|
|
244
|
+
throw new CaatingaError5(
|
|
245
|
+
`Simulation for "${contractName}.${method}" did not return a result.`,
|
|
246
|
+
CaatingaErrorCode5.READ_RESULT_MISSING,
|
|
247
|
+
`Expected "${contractName}.${method}" to expose a simulation result. Use debugRaw to inspect the generated binding output.`
|
|
248
|
+
);
|
|
249
|
+
}
|
|
250
|
+
|
|
251
|
+
// src/client/transaction-submit.ts
|
|
252
|
+
import { CaatingaError as CaatingaError6, CaatingaErrorCode as CaatingaErrorCode6 } from "@caatinga/core/browser";
|
|
253
|
+
async function submitTransaction(transaction, signTransaction, contractName, method, rpcUrl) {
|
|
254
|
+
const candidate = transaction;
|
|
255
|
+
if (typeof candidate.signAndSend === "function") {
|
|
256
|
+
try {
|
|
257
|
+
const raw = await candidate.signAndSend.call(transaction, { signTransaction });
|
|
258
|
+
assertSubmitResultRecognized(raw, contractName, method);
|
|
259
|
+
return raw;
|
|
260
|
+
} catch (error) {
|
|
261
|
+
if (error instanceof CaatingaError6) {
|
|
262
|
+
throw error;
|
|
263
|
+
}
|
|
264
|
+
throw new CaatingaError6(
|
|
265
|
+
`Failed to submit XDR for "${contractName}.${method}".`,
|
|
266
|
+
CaatingaErrorCode6.XDR_SUBMIT_FAILED,
|
|
267
|
+
`RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
|
|
268
|
+
error
|
|
269
|
+
);
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (typeof candidate.send === "function") {
|
|
273
|
+
try {
|
|
274
|
+
const raw = await candidate.send.call(transaction);
|
|
275
|
+
assertSubmitResultRecognized(raw, contractName, method);
|
|
276
|
+
return raw;
|
|
277
|
+
} catch (error) {
|
|
278
|
+
if (error instanceof CaatingaError6) {
|
|
279
|
+
throw error;
|
|
280
|
+
}
|
|
281
|
+
throw new CaatingaError6(
|
|
282
|
+
`Failed to submit XDR for "${contractName}.${method}".`,
|
|
283
|
+
CaatingaErrorCode6.XDR_SUBMIT_FAILED,
|
|
284
|
+
`RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
|
|
285
|
+
error
|
|
286
|
+
);
|
|
287
|
+
}
|
|
288
|
+
}
|
|
289
|
+
throw new CaatingaError6(
|
|
290
|
+
`Binding transaction for "${contractName}.${method}" cannot be submitted.`,
|
|
291
|
+
CaatingaErrorCode6.XDR_SUBMIT_FAILED,
|
|
292
|
+
"Regenerate bindings or provide a compatible binding adapter."
|
|
293
|
+
);
|
|
294
|
+
}
|
|
295
|
+
function assertSubmitResultRecognized(raw, contractName, method) {
|
|
296
|
+
if (raw === null || typeof raw !== "object") {
|
|
297
|
+
return;
|
|
298
|
+
}
|
|
299
|
+
const record = raw;
|
|
300
|
+
const hasTransactionId = "txHash" in record || "transactionHash" in record || "hash" in record || hasNestedSendTransactionResponseHash(record);
|
|
301
|
+
const hasResult = "result" in record;
|
|
302
|
+
if (hasTransactionId || hasResult) {
|
|
303
|
+
return;
|
|
304
|
+
}
|
|
305
|
+
throw new CaatingaError6(
|
|
306
|
+
`Submit returned an unrecognized payload for "${contractName}.${method}".`,
|
|
307
|
+
CaatingaErrorCode6.XDR_RESULT_FAILED,
|
|
308
|
+
"Expected txHash, transactionHash, hash, sendTransactionResponse.hash, or result on the submit response. Use debugRaw to inspect the binding output."
|
|
309
|
+
);
|
|
310
|
+
}
|
|
311
|
+
function hasNestedSendTransactionResponseHash(record) {
|
|
312
|
+
const response = record.sendTransactionResponse;
|
|
313
|
+
return response !== null && typeof response === "object" && "hash" in response;
|
|
314
|
+
}
|
|
315
|
+
function normalizeSubmitResult(raw) {
|
|
316
|
+
const candidate = raw;
|
|
317
|
+
return {
|
|
318
|
+
transactionHash: candidate.txHash ?? candidate.transactionHash ?? candidate.hash ?? candidate.sendTransactionResponse?.hash,
|
|
319
|
+
result: candidate.result
|
|
320
|
+
};
|
|
321
|
+
}
|
|
322
|
+
|
|
115
323
|
// src/client/caatinga-contract-client.ts
|
|
116
324
|
var CaatingaContractClient = class {
|
|
117
325
|
constructor(config, contractName, registration, bindingAdapter = createDefaultBindingAdapter(
|
|
@@ -152,28 +360,29 @@ var CaatingaContractClient = class {
|
|
|
152
360
|
let signedXdr;
|
|
153
361
|
const signTransaction = async (xdr2) => {
|
|
154
362
|
try {
|
|
155
|
-
signedXdr = await
|
|
363
|
+
signedXdr = await withWalletTimeout(
|
|
156
364
|
"signTransaction",
|
|
365
|
+
this.config.walletTimeout,
|
|
157
366
|
() => this.config.wallet.signTransaction({
|
|
158
367
|
xdr: xdr2,
|
|
159
368
|
networkPassphrase: this.config.network.networkPassphrase
|
|
160
369
|
})
|
|
161
370
|
);
|
|
162
371
|
} catch (error) {
|
|
163
|
-
if (error instanceof
|
|
372
|
+
if (error instanceof CaatingaError7) {
|
|
164
373
|
throw error;
|
|
165
374
|
}
|
|
166
|
-
throw new
|
|
375
|
+
throw new CaatingaError7(
|
|
167
376
|
`Failed to sign XDR for "${this.contractName}.${method}".`,
|
|
168
|
-
|
|
377
|
+
CaatingaErrorCode7.XDR_SIGN_FAILED,
|
|
169
378
|
"Connect a wallet and approve the transaction.",
|
|
170
379
|
error
|
|
171
380
|
);
|
|
172
381
|
}
|
|
173
382
|
if (typeof signedXdr !== "string" || signedXdr.trim().length === 0) {
|
|
174
|
-
throw new
|
|
383
|
+
throw new CaatingaError7(
|
|
175
384
|
`Failed to sign XDR for "${this.contractName}.${method}".`,
|
|
176
|
-
|
|
385
|
+
CaatingaErrorCode7.XDR_SIGN_FAILED,
|
|
177
386
|
"Wallet returned an empty or invalid signed XDR. The user may have dismissed the signing prompt.",
|
|
178
387
|
signedXdr
|
|
179
388
|
);
|
|
@@ -188,9 +397,9 @@ var CaatingaContractClient = class {
|
|
|
188
397
|
this.config.network.rpcUrl
|
|
189
398
|
);
|
|
190
399
|
if (typeof transaction.signAndSend === "function" && signedXdr === void 0) {
|
|
191
|
-
throw new
|
|
400
|
+
throw new CaatingaError7(
|
|
192
401
|
`Failed to sign XDR for "${this.contractName}.${method}".`,
|
|
193
|
-
|
|
402
|
+
CaatingaErrorCode7.XDR_SIGN_FAILED,
|
|
194
403
|
"Wallet returned an empty or invalid signed XDR. The generated transaction did not request a wallet signature."
|
|
195
404
|
);
|
|
196
405
|
}
|
|
@@ -244,17 +453,18 @@ var CaatingaContractClient = class {
|
|
|
244
453
|
});
|
|
245
454
|
let publicKey;
|
|
246
455
|
try {
|
|
247
|
-
publicKey = await
|
|
456
|
+
publicKey = await withWalletTimeout(
|
|
248
457
|
"getPublicKey",
|
|
458
|
+
this.config.walletTimeout,
|
|
249
459
|
() => this.config.wallet.getPublicKey()
|
|
250
460
|
);
|
|
251
461
|
} catch (error) {
|
|
252
|
-
if (error instanceof
|
|
462
|
+
if (error instanceof CaatingaError7) {
|
|
253
463
|
throw error;
|
|
254
464
|
}
|
|
255
|
-
throw new
|
|
465
|
+
throw new CaatingaError7(
|
|
256
466
|
`Wallet is not connected or the public key is unavailable for "${this.contractName}".`,
|
|
257
|
-
|
|
467
|
+
CaatingaErrorCode7.WALLET_NOT_CONNECTED,
|
|
258
468
|
"Connect the wallet and grant account access, then retry.",
|
|
259
469
|
error
|
|
260
470
|
);
|
|
@@ -268,179 +478,7 @@ var CaatingaContractClient = class {
|
|
|
268
478
|
const transaction = await this.bindingAdapter.callMethod({ client, method, args });
|
|
269
479
|
return { contractId, transaction };
|
|
270
480
|
}
|
|
271
|
-
withWalletTimeout(label, fn) {
|
|
272
|
-
const timeoutMs = this.config.walletTimeout;
|
|
273
|
-
if (timeoutMs === void 0 || timeoutMs <= 0) {
|
|
274
|
-
return fn();
|
|
275
|
-
}
|
|
276
|
-
let timedOut = false;
|
|
277
|
-
return new Promise((resolve, reject) => {
|
|
278
|
-
const timer = setTimeout(() => {
|
|
279
|
-
timedOut = true;
|
|
280
|
-
reject(
|
|
281
|
-
new CaatingaError4(
|
|
282
|
-
`Wallet "${label}" timed out after ${timeoutMs}ms.`,
|
|
283
|
-
CaatingaErrorCode4.WALLET_TIMEOUT,
|
|
284
|
-
"Ensure the wallet adapter rejects on user dismissal, or increase walletTimeout."
|
|
285
|
-
)
|
|
286
|
-
);
|
|
287
|
-
}, timeoutMs);
|
|
288
|
-
fn().then(
|
|
289
|
-
(value) => {
|
|
290
|
-
if (timedOut) {
|
|
291
|
-
return;
|
|
292
|
-
}
|
|
293
|
-
clearTimeout(timer);
|
|
294
|
-
resolve(value);
|
|
295
|
-
},
|
|
296
|
-
(error) => {
|
|
297
|
-
if (timedOut) {
|
|
298
|
-
return;
|
|
299
|
-
}
|
|
300
|
-
clearTimeout(timer);
|
|
301
|
-
reject(error);
|
|
302
|
-
}
|
|
303
|
-
);
|
|
304
|
-
});
|
|
305
|
-
}
|
|
306
481
|
};
|
|
307
|
-
function splitArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
308
|
-
return {
|
|
309
|
-
args: argsOrOptions,
|
|
310
|
-
debugRaw: maybeOptions?.debugRaw ?? false
|
|
311
|
-
};
|
|
312
|
-
}
|
|
313
|
-
function splitInvokeArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
314
|
-
const looksLikeOptions = argsOrOptions !== void 0 && ("debugXdr" in argsOrOptions || "debugRaw" in argsOrOptions) && maybeOptions === void 0;
|
|
315
|
-
if (looksLikeOptions) {
|
|
316
|
-
const options = argsOrOptions;
|
|
317
|
-
return {
|
|
318
|
-
args: void 0,
|
|
319
|
-
debugXdr: options.debugXdr ?? false,
|
|
320
|
-
debugRaw: options.debugRaw ?? false
|
|
321
|
-
};
|
|
322
|
-
}
|
|
323
|
-
return {
|
|
324
|
-
args: argsOrOptions,
|
|
325
|
-
debugXdr: maybeOptions?.debugXdr ?? false,
|
|
326
|
-
debugRaw: maybeOptions?.debugRaw ?? false
|
|
327
|
-
};
|
|
328
|
-
}
|
|
329
|
-
function splitReadArgsAndOptions(argsOrOptions, maybeOptions) {
|
|
330
|
-
const looksLikeOptions = argsOrOptions !== void 0 && "debugRaw" in argsOrOptions && maybeOptions === void 0;
|
|
331
|
-
if (looksLikeOptions) {
|
|
332
|
-
const options = argsOrOptions;
|
|
333
|
-
return {
|
|
334
|
-
args: void 0,
|
|
335
|
-
debugRaw: options.debugRaw ?? false
|
|
336
|
-
};
|
|
337
|
-
}
|
|
338
|
-
return {
|
|
339
|
-
args: argsOrOptions,
|
|
340
|
-
debugRaw: maybeOptions?.debugRaw ?? false
|
|
341
|
-
};
|
|
342
|
-
}
|
|
343
|
-
async function submitTransaction(transaction, signTransaction, contractName, method, rpcUrl) {
|
|
344
|
-
const candidate = transaction;
|
|
345
|
-
if (typeof candidate.signAndSend === "function") {
|
|
346
|
-
try {
|
|
347
|
-
const raw = await candidate.signAndSend.call(transaction, { signTransaction });
|
|
348
|
-
assertSubmitResultRecognized(raw, contractName, method);
|
|
349
|
-
return raw;
|
|
350
|
-
} catch (error) {
|
|
351
|
-
if (error instanceof CaatingaError4) {
|
|
352
|
-
throw error;
|
|
353
|
-
}
|
|
354
|
-
throw new CaatingaError4(
|
|
355
|
-
`Failed to submit XDR for "${contractName}.${method}".`,
|
|
356
|
-
CaatingaErrorCode4.XDR_SUBMIT_FAILED,
|
|
357
|
-
`RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
|
|
358
|
-
error
|
|
359
|
-
);
|
|
360
|
-
}
|
|
361
|
-
}
|
|
362
|
-
if (typeof candidate.send === "function") {
|
|
363
|
-
try {
|
|
364
|
-
const raw = await candidate.send.call(transaction);
|
|
365
|
-
assertSubmitResultRecognized(raw, contractName, method);
|
|
366
|
-
return raw;
|
|
367
|
-
} catch (error) {
|
|
368
|
-
if (error instanceof CaatingaError4) {
|
|
369
|
-
throw error;
|
|
370
|
-
}
|
|
371
|
-
throw new CaatingaError4(
|
|
372
|
-
`Failed to submit XDR for "${contractName}.${method}".`,
|
|
373
|
-
CaatingaErrorCode4.XDR_SUBMIT_FAILED,
|
|
374
|
-
`RPC: ${rpcUrl}. Check wallet signature and RPC connectivity.`,
|
|
375
|
-
error
|
|
376
|
-
);
|
|
377
|
-
}
|
|
378
|
-
}
|
|
379
|
-
throw new CaatingaError4(
|
|
380
|
-
`Binding transaction for "${contractName}.${method}" cannot be submitted.`,
|
|
381
|
-
CaatingaErrorCode4.XDR_SUBMIT_FAILED,
|
|
382
|
-
"Regenerate bindings or provide a compatible binding adapter."
|
|
383
|
-
);
|
|
384
|
-
}
|
|
385
|
-
async function prepareReadTransaction(transaction, contractName, method, rpcUrl) {
|
|
386
|
-
const candidate = transaction;
|
|
387
|
-
if (typeof candidate.prepare !== "function") {
|
|
388
|
-
return transaction;
|
|
389
|
-
}
|
|
390
|
-
try {
|
|
391
|
-
return await candidate.prepare.call(transaction);
|
|
392
|
-
} catch (error) {
|
|
393
|
-
if (error instanceof CaatingaError4) {
|
|
394
|
-
throw error;
|
|
395
|
-
}
|
|
396
|
-
throw new CaatingaError4(
|
|
397
|
-
`Failed to prepare XDR for "${contractName}.${method}".`,
|
|
398
|
-
CaatingaErrorCode4.XDR_PREPARE_FAILED,
|
|
399
|
-
`RPC: ${rpcUrl}. Check connectivity, simulation errors, and binding compatibility.`,
|
|
400
|
-
error
|
|
401
|
-
);
|
|
402
|
-
}
|
|
403
|
-
}
|
|
404
|
-
function readSimulationResult(raw, contractName, method) {
|
|
405
|
-
if (raw !== null && typeof raw === "object" && "result" in raw) {
|
|
406
|
-
const result = raw.result;
|
|
407
|
-
if (result !== void 0) {
|
|
408
|
-
return result;
|
|
409
|
-
}
|
|
410
|
-
}
|
|
411
|
-
throw new CaatingaError4(
|
|
412
|
-
`Simulation for "${contractName}.${method}" did not return a result.`,
|
|
413
|
-
CaatingaErrorCode4.READ_RESULT_MISSING,
|
|
414
|
-
`Expected "${contractName}.${method}" to expose a simulation result. Use debugRaw to inspect the generated binding output.`
|
|
415
|
-
);
|
|
416
|
-
}
|
|
417
|
-
function assertSubmitResultRecognized(raw, contractName, method) {
|
|
418
|
-
if (raw === null || typeof raw !== "object") {
|
|
419
|
-
return;
|
|
420
|
-
}
|
|
421
|
-
const record = raw;
|
|
422
|
-
const hasTransactionId = "txHash" in record || "transactionHash" in record || "hash" in record || hasNestedSendTransactionResponseHash(record);
|
|
423
|
-
const hasResult = "result" in record;
|
|
424
|
-
if (hasTransactionId || hasResult) {
|
|
425
|
-
return;
|
|
426
|
-
}
|
|
427
|
-
throw new CaatingaError4(
|
|
428
|
-
`Submit returned an unrecognized payload for "${contractName}.${method}".`,
|
|
429
|
-
CaatingaErrorCode4.XDR_RESULT_FAILED,
|
|
430
|
-
"Expected txHash, transactionHash, hash, sendTransactionResponse.hash, or result on the submit response. Use debugRaw to inspect the binding output."
|
|
431
|
-
);
|
|
432
|
-
}
|
|
433
|
-
function hasNestedSendTransactionResponseHash(record) {
|
|
434
|
-
const response = record.sendTransactionResponse;
|
|
435
|
-
return response !== null && typeof response === "object" && "hash" in response;
|
|
436
|
-
}
|
|
437
|
-
function normalizeSubmitResult(raw) {
|
|
438
|
-
const candidate = raw;
|
|
439
|
-
return {
|
|
440
|
-
transactionHash: candidate.txHash ?? candidate.transactionHash ?? candidate.hash ?? candidate.sendTransactionResponse?.hash,
|
|
441
|
-
result: candidate.result
|
|
442
|
-
};
|
|
443
|
-
}
|
|
444
482
|
|
|
445
483
|
// src/client/create-caatinga-client.ts
|
|
446
484
|
function createCaatingaClient(config) {
|
|
@@ -448,9 +486,9 @@ function createCaatingaClient(config) {
|
|
|
448
486
|
contract(contractName) {
|
|
449
487
|
const registration = config.contracts[contractName];
|
|
450
488
|
if (!registration) {
|
|
451
|
-
throw new
|
|
489
|
+
throw new CaatingaError8(
|
|
452
490
|
`Contract "${contractName}" is not registered.`,
|
|
453
|
-
|
|
491
|
+
CaatingaErrorCode8.CONTRACT_NOT_FOUND,
|
|
454
492
|
"Add the contract binding to createCaatingaClient()."
|
|
455
493
|
);
|
|
456
494
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@caatinga/client",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "2.0.0",
|
|
4
4
|
"description": "Browser and Node client for Soroban smart contracts — connects generated bindings, Caatinga artifacts, and wallet adapters",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"stellar",
|
|
@@ -51,7 +51,7 @@
|
|
|
51
51
|
"LICENSE"
|
|
52
52
|
],
|
|
53
53
|
"dependencies": {
|
|
54
|
-
"@caatinga/core": "^0.
|
|
54
|
+
"@caatinga/core": "^2.0.0"
|
|
55
55
|
},
|
|
56
56
|
"devDependencies": {
|
|
57
57
|
"tsup": "^8.3.5",
|