@aibtc/mcp-server 1.43.0 → 1.45.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/config/sponsor.d.ts +8 -0
- package/dist/config/sponsor.d.ts.map +1 -1
- package/dist/config/sponsor.js +10 -0
- package/dist/config/sponsor.js.map +1 -1
- package/dist/services/hiro-api.d.ts +3 -0
- package/dist/services/hiro-api.d.ts.map +1 -1
- package/dist/services/hiro-api.js.map +1 -1
- package/dist/services/nonce-tracker.d.ts +135 -0
- package/dist/services/nonce-tracker.d.ts.map +1 -0
- package/dist/services/nonce-tracker.js +315 -0
- package/dist/services/nonce-tracker.js.map +1 -0
- package/dist/services/wallet-manager.d.ts +1 -1
- package/dist/services/wallet-manager.d.ts.map +1 -1
- package/dist/services/wallet-manager.js +10 -10
- package/dist/services/wallet-manager.js.map +1 -1
- package/dist/tools/arxiv-research.tools.d.ts +16 -0
- package/dist/tools/arxiv-research.tools.d.ts.map +1 -0
- package/dist/tools/arxiv-research.tools.js +433 -0
- package/dist/tools/arxiv-research.tools.js.map +1 -0
- package/dist/tools/inbox.tools.js +23 -18
- package/dist/tools/inbox.tools.js.map +1 -1
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +9 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/nonce.tools.d.ts +11 -0
- package/dist/tools/nonce.tools.d.ts.map +1 -0
- package/dist/tools/nonce.tools.js +689 -0
- package/dist/tools/nonce.tools.js.map +1 -0
- package/dist/tools/skill-mappings.d.ts.map +1 -1
- package/dist/tools/skill-mappings.js +20 -9
- package/dist/tools/skill-mappings.js.map +1 -1
- package/dist/tools/wallet-management.tools.js +1 -1
- package/dist/tools/wallet-management.tools.js.map +1 -1
- package/dist/tools/yield-dashboard.tools.d.ts +17 -0
- package/dist/tools/yield-dashboard.tools.d.ts.map +1 -0
- package/dist/tools/yield-dashboard.tools.js +559 -0
- package/dist/tools/yield-dashboard.tools.js.map +1 -0
- package/dist/transactions/builder.d.ts +9 -20
- package/dist/transactions/builder.d.ts.map +1 -1
- package/dist/transactions/builder.js +34 -92
- package/dist/transactions/builder.js.map +1 -1
- package/dist/transactions/sponsor-builder.d.ts +6 -12
- package/dist/transactions/sponsor-builder.d.ts.map +1 -1
- package/dist/transactions/sponsor-builder.js +81 -39
- package/dist/transactions/sponsor-builder.js.map +1 -1
- package/dist/utils/relay-health.d.ts +14 -5
- package/dist/utils/relay-health.d.ts.map +1 -1
- package/dist/utils/relay-health.js +60 -76
- package/dist/utils/relay-health.js.map +1 -1
- package/dist/yield-hunter/index.js +4 -4
- package/dist/yield-hunter/index.js.map +1 -1
- package/package.json +1 -1
- package/skill/SKILL.md +1 -1
|
@@ -3,113 +3,63 @@ import { hexToBytes } from "@stacks/common";
|
|
|
3
3
|
import { getStacksNetwork, getApiBaseUrl } from "../config/networks.js";
|
|
4
4
|
import { getHiroApi } from "../services/hiro-api.js";
|
|
5
5
|
import { resolveDefaultFee } from "../utils/fee.js";
|
|
6
|
+
import { getTrackedNonce, recordNonceUsed, resetTrackedNonce, reconcileWithChain, } from "../services/nonce-tracker.js";
|
|
6
7
|
// ---------------------------------------------------------------------------
|
|
7
|
-
// Pending nonce tracking (
|
|
8
|
+
// Pending nonce tracking (unified via SharedNonceTracker, issue #413)
|
|
9
|
+
//
|
|
10
|
+
// All nonce state is now managed by src/services/nonce-tracker.ts which
|
|
11
|
+
// persists to ~/.aibtc/nonce-state.json. This module delegates to the tracker
|
|
12
|
+
// and keeps the same public API surface for backward compatibility.
|
|
8
13
|
// ---------------------------------------------------------------------------
|
|
9
|
-
/**
|
|
10
|
-
* How long a locally-tracked pending nonce is considered fresh.
|
|
11
|
-
* If no new transaction has been broadcast within this window the counter is
|
|
12
|
-
* stale (the tx likely confirmed or was dropped) and we fall back to the
|
|
13
|
-
* network value on the next call.
|
|
14
|
-
*/
|
|
15
|
-
const STALE_NONCE_MS = 10 * 60 * 1000; // 10 minutes
|
|
16
|
-
/**
|
|
17
|
-
* Maximum number of addresses tracked simultaneously in pendingNonces and
|
|
18
|
-
* pendingNonceTimestamps. When this limit is reached the oldest entry (by
|
|
19
|
-
* insertion order) is evicted before a new one is added. This prevents
|
|
20
|
-
* unbounded memory growth in long-running server processes (issue #336).
|
|
21
|
-
*/
|
|
22
|
-
export const MAX_NONCE_ENTRIES = 100;
|
|
23
|
-
/**
|
|
24
|
-
* Evict the oldest entry from a Map when it has reached MAX_NONCE_ENTRIES.
|
|
25
|
-
* JS Maps iterate in insertion order, so map.keys().next() yields the oldest
|
|
26
|
-
* key — no additional bookkeeping is needed.
|
|
27
|
-
*/
|
|
28
|
-
function evictOldestIfFull(map) {
|
|
29
|
-
if (map.size >= MAX_NONCE_ENTRIES) {
|
|
30
|
-
const oldestKey = map.keys().next().value;
|
|
31
|
-
if (oldestKey !== undefined) {
|
|
32
|
-
map.delete(oldestKey);
|
|
33
|
-
}
|
|
34
|
-
}
|
|
35
|
-
}
|
|
36
|
-
/**
|
|
37
|
-
* In-memory map of STX address -> next expected nonce for non-sponsored txs.
|
|
38
|
-
* Updated after each successful broadcast so sequential calls don't re-use
|
|
39
|
-
* the same network nonce before the first tx lands in the mempool.
|
|
40
|
-
* Bounded to MAX_NONCE_ENTRIES entries; oldest evicted on overflow (issue #336).
|
|
41
|
-
*/
|
|
42
|
-
const pendingNonces = new Map();
|
|
43
|
-
/**
|
|
44
|
-
* Tracks when each address last advanced its local nonce counter.
|
|
45
|
-
* Used to detect stale entries: if no transaction was sent within STALE_NONCE_MS
|
|
46
|
-
* the counter is expired and the network value is authoritative again.
|
|
47
|
-
* Bounded to MAX_NONCE_ENTRIES entries; oldest evicted on overflow (issue #336).
|
|
48
|
-
*/
|
|
49
|
-
const pendingNonceTimestamps = new Map();
|
|
50
|
-
/**
|
|
51
|
-
* Exported references to the internal nonce Maps for unit testing only.
|
|
52
|
-
* Do not use these outside of test files.
|
|
53
|
-
*/
|
|
54
|
-
export const _testingNonceMaps = {
|
|
55
|
-
pendingNonces,
|
|
56
|
-
pendingNonceTimestamps,
|
|
57
|
-
STALE_NONCE_MS,
|
|
58
|
-
};
|
|
59
14
|
/**
|
|
60
15
|
* Reset the pending nonce for an address (called on wallet unlock/lock/switch
|
|
61
16
|
* so the counter re-syncs with the chain on the next transaction).
|
|
62
17
|
*/
|
|
63
|
-
export function resetPendingNonce(address) {
|
|
64
|
-
|
|
65
|
-
pendingNonceTimestamps.delete(address);
|
|
18
|
+
export async function resetPendingNonce(address) {
|
|
19
|
+
await resetTrackedNonce(address);
|
|
66
20
|
}
|
|
67
21
|
/**
|
|
68
22
|
* Force-resync the local pending nonce for an address.
|
|
69
23
|
* Identical to resetPendingNonce but exported under a name that makes the
|
|
70
24
|
* intent clear for the recover_sponsor_nonce tool's resync-local-nonce action.
|
|
71
25
|
*/
|
|
72
|
-
export function forceResyncNonce(address) {
|
|
73
|
-
resetPendingNonce(address);
|
|
26
|
+
export async function forceResyncNonce(address) {
|
|
27
|
+
await resetPendingNonce(address);
|
|
74
28
|
}
|
|
75
29
|
/**
|
|
76
30
|
* Fetch the next nonce to use for `address`.
|
|
77
31
|
*
|
|
78
32
|
* Algorithm:
|
|
79
|
-
* 1.
|
|
80
|
-
* 2.
|
|
81
|
-
*
|
|
82
|
-
*
|
|
33
|
+
* 1. Check the shared nonce tracker for a locally-tracked next nonce.
|
|
34
|
+
* 2. Fetch `possible_next_nonce` and `detected_missing_nonces` from Hiro.
|
|
35
|
+
* 3. Reconcile: if chain advanced past local, update tracker.
|
|
36
|
+
* 4. Return max(chain_next, local_tracked) so rapid sequential calls
|
|
83
37
|
* get strictly increasing nonces even before the mempool reflects the first tx.
|
|
84
|
-
*
|
|
85
|
-
* can cause the queue to stall until the gaps are filled.
|
|
38
|
+
* 5. Warn if the network reports missing nonces.
|
|
86
39
|
*/
|
|
87
40
|
async function getNextNonce(address, network) {
|
|
88
|
-
//
|
|
89
|
-
const
|
|
90
|
-
const isStale = lastAdvanced !== undefined && Date.now() - lastAdvanced > STALE_NONCE_MS;
|
|
91
|
-
if (isStale) {
|
|
92
|
-
pendingNonces.delete(address);
|
|
93
|
-
pendingNonceTimestamps.delete(address);
|
|
94
|
-
}
|
|
95
|
-
const pending = pendingNonces.get(address) ?? 0n;
|
|
41
|
+
// Read local tracker state (no network call)
|
|
42
|
+
const localNext = await getTrackedNonce(address);
|
|
96
43
|
try {
|
|
97
44
|
const hiroApi = getHiroApi(network);
|
|
98
45
|
const nonceInfo = await hiroApi.getNonceInfo(address);
|
|
99
46
|
const networkNext = BigInt(nonceInfo.possible_next_nonce);
|
|
47
|
+
// Reconcile: if chain advanced past local state, update the tracker
|
|
48
|
+
await reconcileWithChain(address, nonceInfo.possible_next_nonce);
|
|
100
49
|
// Warn about detected nonce gaps that could stall the queue.
|
|
101
50
|
if (nonceInfo.detected_missing_nonces && nonceInfo.detected_missing_nonces.length > 0) {
|
|
102
51
|
console.warn(`[nonce] detected_missing_nonces for ${address}: [${nonceInfo.detected_missing_nonces.join(", ")}]. ` +
|
|
103
52
|
`These gaps may stall pending transactions. Use recover_sponsor_nonce with action=fill-gaps to resolve.`);
|
|
104
53
|
}
|
|
105
|
-
|
|
54
|
+
const localNextBig = localNext !== null ? BigInt(localNext) : 0n;
|
|
55
|
+
return networkNext > localNextBig ? networkNext : localNextBig;
|
|
106
56
|
}
|
|
107
57
|
catch (err) {
|
|
108
58
|
// Fallback: if we have a fresh local counter, use it to keep the queue moving
|
|
109
59
|
// even when Hiro is temporarily unreachable (e.g., between rapid sequential calls).
|
|
110
|
-
if (
|
|
111
|
-
console.warn(`[nonce] API call failed, using local
|
|
112
|
-
return
|
|
60
|
+
if (localNext !== null && localNext > 0) {
|
|
61
|
+
console.warn(`[nonce] API call failed, using local tracked nonce (${localNext}) for ${address}:`, err);
|
|
62
|
+
return BigInt(localNext);
|
|
113
63
|
}
|
|
114
64
|
throw err;
|
|
115
65
|
}
|
|
@@ -118,22 +68,14 @@ async function getNextNonce(address, network) {
|
|
|
118
68
|
* Record that a transaction with `nonce` was successfully broadcast for
|
|
119
69
|
* `address`, so the next call advances past it.
|
|
120
70
|
*
|
|
121
|
-
*
|
|
71
|
+
* @param txid - Optional transaction ID for the pending log. Pass empty string
|
|
72
|
+
* if not available (e.g., legacy callers).
|
|
122
73
|
*/
|
|
123
|
-
export function advancePendingNonce(address, nonce) {
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
// Only evict when this is a new address — updates to existing keys don't
|
|
129
|
-
// change Map size so no eviction is needed.
|
|
130
|
-
if (!pendingNonces.has(address)) {
|
|
131
|
-
evictOldestIfFull(pendingNonces);
|
|
132
|
-
evictOldestIfFull(pendingNonceTimestamps);
|
|
133
|
-
}
|
|
134
|
-
pendingNonces.set(address, next);
|
|
135
|
-
pendingNonceTimestamps.set(address, Date.now());
|
|
136
|
-
}
|
|
74
|
+
export function advancePendingNonce(address, nonce, txid = "") {
|
|
75
|
+
// Delegate to shared tracker (fire-and-forget since callers are sync)
|
|
76
|
+
recordNonceUsed(address, Number(nonce), txid).catch((err) => {
|
|
77
|
+
console.error(`[nonce] Failed to record nonce ${nonce} for ${address}:`, err);
|
|
78
|
+
});
|
|
137
79
|
}
|
|
138
80
|
/**
|
|
139
81
|
* Transfer STX tokens to a recipient
|
|
@@ -160,7 +102,7 @@ export async function transferStx(account, recipient, amount, memo, fee) {
|
|
|
160
102
|
if ("error" in broadcastResponse) {
|
|
161
103
|
throw new Error(`Broadcast failed: ${broadcastResponse.error} - ${broadcastResponse.reason}`);
|
|
162
104
|
}
|
|
163
|
-
advancePendingNonce(account.address, nonce);
|
|
105
|
+
advancePendingNonce(account.address, nonce, broadcastResponse.txid);
|
|
164
106
|
return {
|
|
165
107
|
txid: broadcastResponse.txid,
|
|
166
108
|
rawTx: transaction.serialize(),
|
|
@@ -193,7 +135,7 @@ export async function callContract(account, options) {
|
|
|
193
135
|
if ("error" in broadcastResponse) {
|
|
194
136
|
throw new Error(`Broadcast failed: ${broadcastResponse.error} - ${broadcastResponse.reason}`);
|
|
195
137
|
}
|
|
196
|
-
advancePendingNonce(account.address, nonce);
|
|
138
|
+
advancePendingNonce(account.address, nonce, broadcastResponse.txid);
|
|
197
139
|
return {
|
|
198
140
|
txid: broadcastResponse.txid,
|
|
199
141
|
rawTx: transaction.serialize(),
|
|
@@ -222,7 +164,7 @@ export async function deployContract(account, options) {
|
|
|
222
164
|
if ("error" in broadcastResponse) {
|
|
223
165
|
throw new Error(`Broadcast failed: ${broadcastResponse.error} - ${broadcastResponse.reason}`);
|
|
224
166
|
}
|
|
225
|
-
advancePendingNonce(account.address, nonce);
|
|
167
|
+
advancePendingNonce(account.address, nonce, broadcastResponse.txid);
|
|
226
168
|
return {
|
|
227
169
|
txid: broadcastResponse.txid,
|
|
228
170
|
rawTx: transaction.serialize(),
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/transactions/builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,oBAAoB,EAEpB,iBAAiB,GAElB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,gBAAgB,CAAC;AAC5C,OAAO,EAAE,gBAAgB,EAAE,aAAa,EAAgB,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,UAAU,EAAE,MAAM,yBAAyB,CAAC;AACrD,OAAO,EAAE,iBAAiB,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"builder.js","sourceRoot":"","sources":["../../src/transactions/builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -13,24 +13,18 @@ export interface SponsorRelayResponse {
|
|
|
13
13
|
retryAfter?: number;
|
|
14
14
|
}
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
*
|
|
19
|
-
* This is the primary entry point for services that need sponsored contract calls.
|
|
16
|
+
* Build and submit a sponsored contract call via the relay.
|
|
17
|
+
* Falls back to direct submission (sender pays fee) when the relay is unavailable.
|
|
20
18
|
*/
|
|
21
19
|
export declare function sponsoredContractCall(account: Account, options: ContractCallOptions, network: Network): Promise<TransferResult>;
|
|
22
20
|
/**
|
|
23
|
-
*
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* This is the primary entry point for services that need sponsored STX transfers.
|
|
21
|
+
* Build and submit a sponsored STX transfer via the relay.
|
|
22
|
+
* Falls back to direct submission (sender pays fee) when the relay is unavailable.
|
|
27
23
|
*/
|
|
28
24
|
export declare function sponsoredStxTransfer(account: Account, recipient: string, amount: bigint, memo: string | undefined, network: Network): Promise<TransferResult>;
|
|
29
25
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
*
|
|
33
|
-
* This is the primary entry point for services that need sponsored contract deployments.
|
|
26
|
+
* Build and submit a sponsored contract deploy via the relay.
|
|
27
|
+
* Falls back to direct submission (sender pays fee) when the relay is unavailable.
|
|
34
28
|
*/
|
|
35
29
|
export declare function sponsoredContractDeploy(account: Account, options: ContractDeployOptions, network: Network): Promise<TransferResult>;
|
|
36
30
|
//# sourceMappingURL=sponsor-builder.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sponsor-builder.d.ts","sourceRoot":"","sources":["../../src/transactions/sponsor-builder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoB,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEvE,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;
|
|
1
|
+
{"version":3,"file":"sponsor-builder.d.ts","sourceRoot":"","sources":["../../src/transactions/sponsor-builder.ts"],"names":[],"mappings":"AAMA,OAAO,EAAoB,KAAK,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAEvE,OAAO,KAAK,EAAE,OAAO,EAAE,mBAAmB,EAAE,qBAAqB,EAAE,cAAc,EAAE,MAAM,cAAc,CAAC;AAwDxG,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,GAAG,CAAC,EAAE,MAAM,CAAC;IACb,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AA8DD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,mBAAmB,EAC5B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,cAAc,CAAC,CAiBzB;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CACxC,OAAO,EAAE,OAAO,EAChB,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,GAAG,SAAS,EACxB,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,cAAc,CAAC,CAczB;AAED;;;GAGG;AACH,wBAAsB,uBAAuB,CAC3C,OAAO,EAAE,OAAO,EAChB,OAAO,EAAE,qBAAqB,EAC9B,OAAO,EAAE,OAAO,GACf,OAAO,CAAC,cAAc,CAAC,CAazB"}
|
|
@@ -1,6 +1,51 @@
|
|
|
1
1
|
import { makeSTXTokenTransfer, makeContractCall, makeContractDeploy, PostConditionMode, } from "@stacks/transactions";
|
|
2
2
|
import { getStacksNetwork } from "../config/networks.js";
|
|
3
|
-
import { getSponsorRelayUrl, getSponsorApiKey } from "../config/sponsor.js";
|
|
3
|
+
import { getSponsorRelayUrl, getSponsorApiKey, isFallbackEnabled } from "../config/sponsor.js";
|
|
4
|
+
import { callContract, transferStx, deployContract } from "./builder.js";
|
|
5
|
+
import { recordNonceUsed } from "../services/nonce-tracker.js";
|
|
6
|
+
import { isRelayHealthy } from "../utils/relay-health.js";
|
|
7
|
+
/**
|
|
8
|
+
* Relay-side error codes and keywords that indicate a nonce conflict on the
|
|
9
|
+
* relay, not a user-side error. When these are present the tx itself is valid
|
|
10
|
+
* and a direct fallback makes sense.
|
|
11
|
+
*/
|
|
12
|
+
const NONCE_FAULT_PATTERNS = [
|
|
13
|
+
"ConflictingNonceInMempool",
|
|
14
|
+
"TooMuchChaining",
|
|
15
|
+
"BadNonce",
|
|
16
|
+
"nonce",
|
|
17
|
+
];
|
|
18
|
+
/**
|
|
19
|
+
* Returns true when a failed relay response is caused by a relay-side nonce
|
|
20
|
+
* problem rather than a user-side error (bad args, insufficient balance, etc).
|
|
21
|
+
*/
|
|
22
|
+
function isRelayNonceFault(response) {
|
|
23
|
+
const code = response.code ?? "";
|
|
24
|
+
const error = response.error ?? "";
|
|
25
|
+
const details = response.details ?? "";
|
|
26
|
+
const haystack = `${code} ${error} ${details}`.toLowerCase();
|
|
27
|
+
return NONCE_FAULT_PATTERNS.some((p) => haystack.includes(p.toLowerCase()));
|
|
28
|
+
}
|
|
29
|
+
/**
|
|
30
|
+
* Decide whether to fall back to direct submission for a relay failure.
|
|
31
|
+
* Returns { shouldFallback: true, reason } or { shouldFallback: false }.
|
|
32
|
+
*/
|
|
33
|
+
async function evaluateFallback(response, network) {
|
|
34
|
+
if (!isFallbackEnabled()) {
|
|
35
|
+
return { shouldFallback: false };
|
|
36
|
+
}
|
|
37
|
+
if (isRelayNonceFault(response)) {
|
|
38
|
+
return {
|
|
39
|
+
shouldFallback: true,
|
|
40
|
+
reason: `relay nonce error: ${response.code ?? response.error}`,
|
|
41
|
+
};
|
|
42
|
+
}
|
|
43
|
+
const healthy = await isRelayHealthy(network);
|
|
44
|
+
if (!healthy) {
|
|
45
|
+
return { shouldFallback: true, reason: "relay unhealthy" };
|
|
46
|
+
}
|
|
47
|
+
return { shouldFallback: false };
|
|
48
|
+
}
|
|
4
49
|
/**
|
|
5
50
|
* Format a failed SponsorRelayResponse into an error message
|
|
6
51
|
*/
|
|
@@ -26,81 +71,78 @@ function resolveSponsorApiKey(account) {
|
|
|
26
71
|
return apiKey;
|
|
27
72
|
}
|
|
28
73
|
/**
|
|
29
|
-
*
|
|
30
|
-
* return a TransferResult. Resolves the API key and handles relay errors.
|
|
74
|
+
* Submit a sponsored transaction to the relay and handle the response.
|
|
31
75
|
*
|
|
32
|
-
*
|
|
76
|
+
* Shared logic for all three sponsored helpers (contract call, STX transfer,
|
|
77
|
+
* contract deploy). Each caller builds its own transaction and provides a
|
|
78
|
+
* fallback function for direct submission when the relay is unavailable.
|
|
33
79
|
*/
|
|
34
|
-
|
|
80
|
+
async function submitSponsoredTransaction(account, transaction, network, directFallback) {
|
|
35
81
|
const apiKey = resolveSponsorApiKey(account);
|
|
36
|
-
const
|
|
82
|
+
const senderNonce = Number(transaction.auth.spendingCondition.nonce);
|
|
83
|
+
const serializedTx = transaction.serialize();
|
|
84
|
+
const response = await submitToSponsorRelay(serializedTx, network, apiKey);
|
|
85
|
+
if (!response.success) {
|
|
86
|
+
const { shouldFallback, reason } = await evaluateFallback(response, network);
|
|
87
|
+
if (shouldFallback) {
|
|
88
|
+
console.warn(`[sponsor] Relay unavailable or nonce error (${reason}), falling back to direct submission (sender pays fee)`);
|
|
89
|
+
const result = await directFallback();
|
|
90
|
+
return { ...result, fallback: true, fallbackReason: reason };
|
|
91
|
+
}
|
|
92
|
+
throw new Error(formatRelayError(response));
|
|
93
|
+
}
|
|
94
|
+
await recordNonceUsed(account.address, senderNonce, response.txid);
|
|
95
|
+
return { txid: response.txid, rawTx: serializedTx };
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Build and submit a sponsored contract call via the relay.
|
|
99
|
+
* Falls back to direct submission (sender pays fee) when the relay is unavailable.
|
|
100
|
+
*/
|
|
101
|
+
export async function sponsoredContractCall(account, options, network) {
|
|
37
102
|
const transaction = await makeContractCall({
|
|
38
103
|
contractAddress: options.contractAddress,
|
|
39
104
|
contractName: options.contractName,
|
|
40
105
|
functionName: options.functionName,
|
|
41
106
|
functionArgs: options.functionArgs,
|
|
42
107
|
senderKey: account.privateKey,
|
|
43
|
-
network:
|
|
108
|
+
network: getStacksNetwork(network),
|
|
44
109
|
postConditionMode: options.postConditionMode || PostConditionMode.Deny,
|
|
45
110
|
postConditions: options.postConditions || [],
|
|
46
111
|
sponsored: true,
|
|
47
112
|
fee: 0n,
|
|
48
113
|
});
|
|
49
|
-
|
|
50
|
-
const response = await submitToSponsorRelay(serializedTx, network, apiKey);
|
|
51
|
-
if (!response.success) {
|
|
52
|
-
throw new Error(formatRelayError(response));
|
|
53
|
-
}
|
|
54
|
-
return { txid: response.txid, rawTx: serializedTx };
|
|
114
|
+
return submitSponsoredTransaction(account, transaction, network, () => callContract(account, options));
|
|
55
115
|
}
|
|
56
116
|
/**
|
|
57
|
-
*
|
|
58
|
-
*
|
|
59
|
-
*
|
|
60
|
-
* This is the primary entry point for services that need sponsored STX transfers.
|
|
117
|
+
* Build and submit a sponsored STX transfer via the relay.
|
|
118
|
+
* Falls back to direct submission (sender pays fee) when the relay is unavailable.
|
|
61
119
|
*/
|
|
62
120
|
export async function sponsoredStxTransfer(account, recipient, amount, memo, network) {
|
|
63
|
-
const apiKey = resolveSponsorApiKey(account);
|
|
64
|
-
const networkName = getStacksNetwork(network);
|
|
65
121
|
const transaction = await makeSTXTokenTransfer({
|
|
66
122
|
recipient,
|
|
67
123
|
amount,
|
|
68
124
|
senderKey: account.privateKey,
|
|
69
|
-
network:
|
|
125
|
+
network: getStacksNetwork(network),
|
|
70
126
|
memo: memo || "",
|
|
71
127
|
sponsored: true,
|
|
72
128
|
fee: 0n,
|
|
73
129
|
});
|
|
74
|
-
|
|
75
|
-
const response = await submitToSponsorRelay(serializedTx, network, apiKey);
|
|
76
|
-
if (!response.success) {
|
|
77
|
-
throw new Error(formatRelayError(response));
|
|
78
|
-
}
|
|
79
|
-
return { txid: response.txid, rawTx: serializedTx };
|
|
130
|
+
return submitSponsoredTransaction(account, transaction, network, () => transferStx(account, recipient, amount, memo));
|
|
80
131
|
}
|
|
81
132
|
/**
|
|
82
|
-
*
|
|
83
|
-
*
|
|
84
|
-
*
|
|
85
|
-
* This is the primary entry point for services that need sponsored contract deployments.
|
|
133
|
+
* Build and submit a sponsored contract deploy via the relay.
|
|
134
|
+
* Falls back to direct submission (sender pays fee) when the relay is unavailable.
|
|
86
135
|
*/
|
|
87
136
|
export async function sponsoredContractDeploy(account, options, network) {
|
|
88
|
-
const apiKey = resolveSponsorApiKey(account);
|
|
89
|
-
const networkName = getStacksNetwork(network);
|
|
90
137
|
const transaction = await makeContractDeploy({
|
|
91
138
|
contractName: options.contractName,
|
|
92
139
|
codeBody: options.codeBody,
|
|
93
140
|
senderKey: account.privateKey,
|
|
94
|
-
network:
|
|
141
|
+
network: getStacksNetwork(network),
|
|
95
142
|
sponsored: true,
|
|
96
143
|
fee: 0n,
|
|
97
144
|
});
|
|
98
|
-
|
|
99
|
-
const response = await submitToSponsorRelay(serializedTx, network, apiKey);
|
|
100
|
-
if (!response.success) {
|
|
101
|
-
throw new Error(formatRelayError(response));
|
|
102
|
-
}
|
|
103
|
-
return { txid: response.txid, rawTx: serializedTx };
|
|
145
|
+
return submitSponsoredTransaction(account, transaction, network, () => deployContract(account, options));
|
|
104
146
|
}
|
|
105
147
|
/**
|
|
106
148
|
* Submit a serialized transaction to the sponsor relay
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"sponsor-builder.js","sourceRoot":"","sources":["../../src/transactions/sponsor-builder.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,kBAAkB,EAClB,iBAAiB,GAClB,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,gBAAgB,EAAgB,MAAM,uBAAuB,CAAC;AACvE,OAAO,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"sponsor-builder.js","sourceRoot":"","sources":["../../src/transactions/sponsor-builder.ts"],"names":[],"mappings":"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"}
|
|
@@ -9,6 +9,7 @@ export interface StuckTransaction {
|
|
|
9
9
|
txid: string;
|
|
10
10
|
nonce: number;
|
|
11
11
|
pendingSeconds: number;
|
|
12
|
+
sponsor_nonce?: number;
|
|
12
13
|
}
|
|
13
14
|
export interface RelayHealthStatus {
|
|
14
15
|
healthy: boolean;
|
|
@@ -29,6 +30,19 @@ export interface RelayHealthStatus {
|
|
|
29
30
|
stuckTransactions?: StuckTransaction[];
|
|
30
31
|
issues?: string[];
|
|
31
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* Known sponsor addresses for each network.
|
|
35
|
+
* Only mainnet has a known relay sponsor address.
|
|
36
|
+
*/
|
|
37
|
+
export declare const SPONSOR_ADDRESSES: Partial<Record<Network, string>>;
|
|
38
|
+
/**
|
|
39
|
+
* Lightweight relay health probe — returns true only if the relay /health
|
|
40
|
+
* endpoint responds within 5 seconds with HTTP 200 and status "ok".
|
|
41
|
+
*
|
|
42
|
+
* Use this on the hot path (e.g., before deciding to fall back to direct
|
|
43
|
+
* submission) where the full checkRelayHealth() diagnostics are unnecessary.
|
|
44
|
+
*/
|
|
45
|
+
export declare function isRelayHealthy(network: Network): Promise<boolean>;
|
|
32
46
|
/**
|
|
33
47
|
* Check relay health and sponsor nonce status
|
|
34
48
|
*/
|
|
@@ -57,9 +71,4 @@ export declare function attemptRbf(network: Network, txids?: string[], apiKey?:
|
|
|
57
71
|
* Gracefully returns { supported: false } if the relay returns 404 or 501.
|
|
58
72
|
*/
|
|
59
73
|
export declare function attemptFillGaps(network: Network, nonces?: number[], apiKey?: string): Promise<RelayRecoveryResult>;
|
|
60
|
-
/**
|
|
61
|
-
* Wait with exponential backoff when relay nonce issues are detected
|
|
62
|
-
* Returns recommended wait time in milliseconds
|
|
63
|
-
*/
|
|
64
|
-
export declare function getRelayBackoffDelay(attempt: number, hasNonceGaps: boolean): number;
|
|
65
74
|
//# sourceMappingURL=relay-health.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"relay-health.d.ts","sourceRoot":"","sources":["../../src/utils/relay-health.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE;QACZ,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,OAAO,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;
|
|
1
|
+
{"version":3,"file":"relay-health.d.ts","sourceRoot":"","sources":["../../src/utils/relay-health.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAGrD,MAAM,WAAW,gBAAgB;IAC/B,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,cAAc,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;CACxB;AAED,MAAM,WAAW,iBAAiB;IAChC,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,WAAW,CAAC,EAAE;QACZ,YAAY,EAAE,MAAM,CAAC;QACrB,WAAW,EAAE,MAAM,GAAG,IAAI,CAAC;QAC3B,YAAY,EAAE,MAAM,CAAC;QACrB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,aAAa,EAAE,MAAM,EAAE,CAAC;QACxB,OAAO,EAAE,OAAO,CAAC;QACjB,QAAQ,EAAE,MAAM,CAAC;QACjB,aAAa,EAAE,OAAO,CAAC;QACvB,SAAS,EAAE,MAAM,CAAC;KACnB,CAAC;IACF,iBAAiB,CAAC,EAAE,gBAAgB,EAAE,CAAC;IACvC,MAAM,CAAC,EAAE,MAAM,EAAE,CAAC;CACnB;AAED;;;GAGG;AACH,eAAO,MAAM,iBAAiB,EAAE,OAAO,CAAC,MAAM,CAAC,OAAO,EAAE,MAAM,CAAC,CAE9D,CAAC;AAEF;;;;;;GAMG;AACH,wBAAsB,cAAc,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAqBvE;AAED;;GAEG;AACH,wBAAsB,gBAAgB,CAAC,OAAO,EAAE,OAAO,GAAG,OAAO,CAAC,iBAAiB,CAAC,CA6HnF;AAED;;GAEG;AACH,wBAAgB,uBAAuB,CAAC,MAAM,EAAE,iBAAiB,GAAG,MAAM,CAuDzE;AAED,MAAM,WAAW,mBAAmB;IAClC,SAAS,EAAE,OAAO,CAAC;IACnB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,OAAO,CAAC;CAClB;AAwDD;;;;;;GAMG;AACH,wBAAgB,UAAU,CAAC,OAAO,EAAE,OAAO,EAAE,KAAK,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAW5G;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,EAAE,MAAM,CAAC,EAAE,MAAM,EAAE,EAAE,MAAM,CAAC,EAAE,MAAM,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAWlH"}
|