@towns-labs/relayer 2.0.13 → 2.1.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.
- package/dist/README.md +1 -1
- package/dist/index.js +145 -147
- package/dist/index.js.map +4 -4
- package/package.json +2 -2
- package/src/rpc/schema/intentTypes.ts +27 -0
- package/src/rpc/schema/prepareCalls.ts +3 -20
- package/src/rpc/schema/sendPreparedCalls.ts +1 -2
package/dist/README.md
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
This folder contains the built output assets for the worker "relayer-worker" generated at 2026-02-
|
|
1
|
+
This folder contains the built output assets for the worker "relayer-worker" generated at 2026-02-16T21:41:19.331Z.
|
package/dist/index.js
CHANGED
|
@@ -23663,6 +23663,7 @@ var ACCOUNT_NOT_DELEGATED = -32009;
|
|
|
23663
23663
|
var QUOTE_EXPIRED = -32010;
|
|
23664
23664
|
var INVALID_QUOTE_SIGNATURE = -32011;
|
|
23665
23665
|
var PAYMENT_EXCEEDS_MAX = -32012;
|
|
23666
|
+
var DRAFT_CONFLICT = -32013;
|
|
23666
23667
|
var ERROR_MESSAGES = {
|
|
23667
23668
|
[PARSE_ERROR]: "Parse error",
|
|
23668
23669
|
[INVALID_REQUEST]: "Invalid Request",
|
|
@@ -23681,7 +23682,8 @@ var ERROR_MESSAGES = {
|
|
|
23681
23682
|
[ACCOUNT_NOT_DELEGATED]: "Account not delegated",
|
|
23682
23683
|
[QUOTE_EXPIRED]: "Quote expired",
|
|
23683
23684
|
[INVALID_QUOTE_SIGNATURE]: "Invalid quote signature",
|
|
23684
|
-
[PAYMENT_EXCEEDS_MAX]: "Payment amount exceeds maximum"
|
|
23685
|
+
[PAYMENT_EXCEEDS_MAX]: "Payment amount exceeds maximum",
|
|
23686
|
+
[DRAFT_CONFLICT]: "Draft conflict"
|
|
23685
23687
|
};
|
|
23686
23688
|
var RpcError2 = class extends Error {
|
|
23687
23689
|
static {
|
|
@@ -23801,7 +23803,7 @@ function isEip7702Delegated(code) {
|
|
|
23801
23803
|
}
|
|
23802
23804
|
__name(isEip7702Delegated, "isEip7702Delegated");
|
|
23803
23805
|
|
|
23804
|
-
// src/
|
|
23806
|
+
// src/rpc/schema/intentTypes.ts
|
|
23805
23807
|
var INTENT_TYPES = {
|
|
23806
23808
|
Intent: [
|
|
23807
23809
|
{ name: "multichain", type: "bool" },
|
|
@@ -23823,60 +23825,39 @@ var INTENT_TYPES = {
|
|
|
23823
23825
|
{ name: "data", type: "bytes" }
|
|
23824
23826
|
]
|
|
23825
23827
|
};
|
|
23828
|
+
|
|
23829
|
+
// src/services/relayer.ts
|
|
23826
23830
|
function createIntentNonceProvider(durableObject, chainId) {
|
|
23827
23831
|
const durableObjectNameFor = /* @__PURE__ */ __name((eoa) => `${chainId}:${eoa.toLowerCase()}`, "durableObjectNameFor");
|
|
23832
|
+
const getStubForEoa = /* @__PURE__ */ __name((eoa) => {
|
|
23833
|
+
const id = durableObject.idFromName(durableObjectNameFor(eoa));
|
|
23834
|
+
return durableObject.get(id);
|
|
23835
|
+
}, "getStubForEoa");
|
|
23836
|
+
const postToNonceDo = /* @__PURE__ */ __name(async (eoa, path, body) => {
|
|
23837
|
+
const stub = getStubForEoa(eoa);
|
|
23838
|
+
return stub.fetch(
|
|
23839
|
+
new Request(`http://do/${path}`, {
|
|
23840
|
+
method: "POST",
|
|
23841
|
+
headers: { "Content-Type": "application/json" },
|
|
23842
|
+
body: JSON.stringify(body)
|
|
23843
|
+
})
|
|
23844
|
+
);
|
|
23845
|
+
}, "postToNonceDo");
|
|
23828
23846
|
return {
|
|
23829
|
-
async acquireNonce(eoa, seqKey = 0n) {
|
|
23830
|
-
const id = durableObject.idFromName(durableObjectNameFor(eoa));
|
|
23831
|
-
const stub = durableObject.get(id);
|
|
23832
|
-
const response = await stub.fetch(
|
|
23833
|
-
new Request("http://do/acquire", {
|
|
23834
|
-
method: "POST",
|
|
23835
|
-
headers: { "Content-Type": "application/json" },
|
|
23836
|
-
body: JSON.stringify({ seqKey: seqKey.toString() })
|
|
23837
|
-
})
|
|
23838
|
-
);
|
|
23839
|
-
if (!response.ok) {
|
|
23840
|
-
const error48 = await response.json();
|
|
23841
|
-
throw new Error(`Failed to acquire intent nonce: ${error48.error}`);
|
|
23842
|
-
}
|
|
23843
|
-
const data = await response.json();
|
|
23844
|
-
return BigInt(data.nonce);
|
|
23845
|
-
},
|
|
23846
|
-
async acquireNonceSynced(eoa, seqKey, onChainSeq) {
|
|
23847
|
-
const id = durableObject.idFromName(durableObjectNameFor(eoa));
|
|
23848
|
-
const stub = durableObject.get(id);
|
|
23849
|
-
const response = await stub.fetch(
|
|
23850
|
-
new Request("http://do/acquire_synced", {
|
|
23851
|
-
method: "POST",
|
|
23852
|
-
headers: { "Content-Type": "application/json" },
|
|
23853
|
-
body: JSON.stringify({
|
|
23854
|
-
seqKey: seqKey.toString(),
|
|
23855
|
-
onChainSeq: onChainSeq.toString()
|
|
23856
|
-
})
|
|
23857
|
-
})
|
|
23858
|
-
);
|
|
23859
|
-
if (!response.ok) {
|
|
23860
|
-
const error48 = await response.json();
|
|
23861
|
-
throw new Error(`Failed to acquire synced intent nonce: ${error48.error}`);
|
|
23862
|
-
}
|
|
23863
|
-
const data = await response.json();
|
|
23864
|
-
return { nonce: BigInt(data.nonce), synced: data.synced };
|
|
23865
|
-
},
|
|
23866
23847
|
async acquireOrGetDraft(eoa, seqKey, onChainSeq, prepareKey) {
|
|
23867
|
-
const
|
|
23868
|
-
|
|
23869
|
-
|
|
23870
|
-
|
|
23871
|
-
|
|
23872
|
-
|
|
23873
|
-
|
|
23874
|
-
|
|
23875
|
-
|
|
23876
|
-
|
|
23877
|
-
|
|
23878
|
-
}
|
|
23879
|
-
|
|
23848
|
+
const response = await postToNonceDo(eoa, "acquire_or_get_draft", {
|
|
23849
|
+
seqKey: seqKey.toString(),
|
|
23850
|
+
onChainSeq: onChainSeq.toString(),
|
|
23851
|
+
draftKey: prepareKey
|
|
23852
|
+
});
|
|
23853
|
+
if (response.status === 409) {
|
|
23854
|
+
const body = await response.json();
|
|
23855
|
+
return {
|
|
23856
|
+
conflict: true,
|
|
23857
|
+
error: body.error,
|
|
23858
|
+
conflictDraftId: body.conflictDraftId
|
|
23859
|
+
};
|
|
23860
|
+
}
|
|
23880
23861
|
if (!response.ok) {
|
|
23881
23862
|
const error48 = await response.json();
|
|
23882
23863
|
throw new Error(`Failed to acquire intent draft: ${error48.error}`);
|
|
@@ -23891,55 +23872,16 @@ function createIntentNonceProvider(durableObject, chainId) {
|
|
|
23891
23872
|
};
|
|
23892
23873
|
},
|
|
23893
23874
|
async markSubmitted(eoa, seqKey, draftId) {
|
|
23894
|
-
const
|
|
23895
|
-
|
|
23896
|
-
|
|
23897
|
-
|
|
23898
|
-
method: "POST",
|
|
23899
|
-
headers: { "Content-Type": "application/json" },
|
|
23900
|
-
body: JSON.stringify({ seqKey: seqKey.toString(), draftId })
|
|
23901
|
-
})
|
|
23902
|
-
);
|
|
23875
|
+
const response = await postToNonceDo(eoa, "mark_submitted", {
|
|
23876
|
+
seqKey: seqKey.toString(),
|
|
23877
|
+
draftId
|
|
23878
|
+
});
|
|
23903
23879
|
if (!response.ok) {
|
|
23904
23880
|
const error48 = await response.json();
|
|
23905
23881
|
throw new Error(`Failed to mark intent draft submitted: ${error48.error}`);
|
|
23906
23882
|
}
|
|
23907
23883
|
const data = await response.json();
|
|
23908
23884
|
return data.status;
|
|
23909
|
-
},
|
|
23910
|
-
async cancelDraft(eoa, seqKey, draftId) {
|
|
23911
|
-
const id = durableObject.idFromName(durableObjectNameFor(eoa));
|
|
23912
|
-
const stub = durableObject.get(id);
|
|
23913
|
-
const response = await stub.fetch(
|
|
23914
|
-
new Request("http://do/cancel_draft", {
|
|
23915
|
-
method: "POST",
|
|
23916
|
-
headers: { "Content-Type": "application/json" },
|
|
23917
|
-
body: JSON.stringify({ seqKey: seqKey.toString(), draftId })
|
|
23918
|
-
})
|
|
23919
|
-
);
|
|
23920
|
-
if (!response.ok) {
|
|
23921
|
-
const error48 = await response.json();
|
|
23922
|
-
throw new Error(`Failed to cancel intent draft: ${error48.error}`);
|
|
23923
|
-
}
|
|
23924
|
-
const data = await response.json();
|
|
23925
|
-
return data.status;
|
|
23926
|
-
},
|
|
23927
|
-
async syncNonce(eoa, seqKey, confirmedSeq) {
|
|
23928
|
-
const id = durableObject.idFromName(durableObjectNameFor(eoa));
|
|
23929
|
-
const stub = durableObject.get(id);
|
|
23930
|
-
const response = await stub.fetch(
|
|
23931
|
-
new Request("http://do/sync", {
|
|
23932
|
-
method: "POST",
|
|
23933
|
-
headers: { "Content-Type": "application/json" },
|
|
23934
|
-
body: JSON.stringify({
|
|
23935
|
-
seqKey: seqKey.toString(),
|
|
23936
|
-
confirmedSeq: confirmedSeq.toString()
|
|
23937
|
-
})
|
|
23938
|
-
})
|
|
23939
|
-
);
|
|
23940
|
-
if (!response.ok) {
|
|
23941
|
-
console.warn("Failed to sync intent nonce for:", eoa);
|
|
23942
|
-
}
|
|
23943
23885
|
}
|
|
23944
23886
|
};
|
|
23945
23887
|
}
|
|
@@ -23953,6 +23895,26 @@ var DEFAULT_GAS_CONFIG = {
|
|
|
23953
23895
|
txGasBuffer: 0n,
|
|
23954
23896
|
allowSimulationFallback: false
|
|
23955
23897
|
};
|
|
23898
|
+
var DEFAULT_INTENT_EXPIRY_SECONDS = 3600n;
|
|
23899
|
+
var MAX_INTENT_EXPIRY_SECONDS_FROM_NOW = 365n * 24n * 60n * 60n;
|
|
23900
|
+
var MILLISECONDS_EPOCH_THRESHOLD = 1000000000000n;
|
|
23901
|
+
function resolveIntentExpirySeconds(rawExpiry, nowSeconds = BigInt(Math.floor(Date.now() / 1e3))) {
|
|
23902
|
+
if (!rawExpiry) {
|
|
23903
|
+
return nowSeconds + DEFAULT_INTENT_EXPIRY_SECONDS;
|
|
23904
|
+
}
|
|
23905
|
+
const expiry = BigInt(rawExpiry);
|
|
23906
|
+
const maxSupportedExpiry = nowSeconds + MAX_INTENT_EXPIRY_SECONDS_FROM_NOW;
|
|
23907
|
+
if (expiry > maxSupportedExpiry) {
|
|
23908
|
+
if (expiry >= MILLISECONDS_EPOCH_THRESHOLD) {
|
|
23909
|
+
throw new Error(
|
|
23910
|
+
`Invalid expiry: ${rawExpiry} appears to be milliseconds; use unix seconds`
|
|
23911
|
+
);
|
|
23912
|
+
}
|
|
23913
|
+
throw new Error(`Invalid expiry: ${rawExpiry} is too far in the future`);
|
|
23914
|
+
}
|
|
23915
|
+
return expiry;
|
|
23916
|
+
}
|
|
23917
|
+
__name(resolveIntentExpirySeconds, "resolveIntentExpirySeconds");
|
|
23956
23918
|
function isPaymentEnabled(payer, paymentToken) {
|
|
23957
23919
|
return payer !== zeroAddress && paymentToken !== zeroAddress;
|
|
23958
23920
|
}
|
|
@@ -23961,6 +23923,14 @@ function calculateCombinedGas(simulationGas, gasConfig, paymentEnabled) {
|
|
|
23961
23923
|
return simulationGas + gasConfig.intentGasBuffer + (paymentEnabled ? gasConfig.paymentGasBuffer : 0n);
|
|
23962
23924
|
}
|
|
23963
23925
|
__name(calculateCombinedGas, "calculateCombinedGas");
|
|
23926
|
+
function normalizeCalls(calls) {
|
|
23927
|
+
return calls.map((call2) => ({
|
|
23928
|
+
to: call2.to,
|
|
23929
|
+
value: call2.value ? BigInt(call2.value) : 0n,
|
|
23930
|
+
data: call2.data ?? "0x"
|
|
23931
|
+
}));
|
|
23932
|
+
}
|
|
23933
|
+
__name(normalizeCalls, "normalizeCalls");
|
|
23964
23934
|
function extractRevertData(error48) {
|
|
23965
23935
|
if (error48 instanceof BaseError2) {
|
|
23966
23936
|
const rawError = error48.walk((e) => e instanceof RawContractError);
|
|
@@ -24047,12 +24017,20 @@ var RelayerService = class {
|
|
|
24047
24017
|
async acquireNonceFromProvider(eoa, seqKey, prepareKey) {
|
|
24048
24018
|
const onChainSeq = await this.fetchOnChainSeq(eoa, seqKey);
|
|
24049
24019
|
const safeOnChainSeq = onChainSeq ?? 0n;
|
|
24050
|
-
const
|
|
24020
|
+
const result = await this.intentNonceProvider.acquireOrGetDraft(
|
|
24051
24021
|
eoa,
|
|
24052
24022
|
seqKey,
|
|
24053
24023
|
safeOnChainSeq,
|
|
24054
24024
|
prepareKey
|
|
24055
24025
|
);
|
|
24026
|
+
if ("conflict" in result) {
|
|
24027
|
+
return {
|
|
24028
|
+
success: false,
|
|
24029
|
+
error: result.error,
|
|
24030
|
+
conflictDraftId: result.conflictDraftId
|
|
24031
|
+
};
|
|
24032
|
+
}
|
|
24033
|
+
const { nonce, draftId, expiresAtMs, fromCache } = result;
|
|
24056
24034
|
if (onChainSeq === null) {
|
|
24057
24035
|
this.logger.debug(
|
|
24058
24036
|
{ eoa, nonce: nonce.toString(), draftId },
|
|
@@ -24119,11 +24097,7 @@ var RelayerService = class {
|
|
|
24119
24097
|
errorCode: "DELEGATION_PENDING"
|
|
24120
24098
|
};
|
|
24121
24099
|
}
|
|
24122
|
-
const calls = request.calls
|
|
24123
|
-
to: c2.to,
|
|
24124
|
-
value: c2.value ? BigInt(c2.value) : 0n,
|
|
24125
|
-
data: c2.data ?? "0x"
|
|
24126
|
-
}));
|
|
24100
|
+
const calls = normalizeCalls(request.calls);
|
|
24127
24101
|
const executionData = encodeAbiParameters(
|
|
24128
24102
|
[
|
|
24129
24103
|
{
|
|
@@ -24137,6 +24111,19 @@ var RelayerService = class {
|
|
|
24137
24111
|
],
|
|
24138
24112
|
[calls]
|
|
24139
24113
|
);
|
|
24114
|
+
const nowSeconds = BigInt(Math.floor(Date.now() / 1e3));
|
|
24115
|
+
const expiry = resolveIntentExpirySeconds(request.expiry, nowSeconds);
|
|
24116
|
+
let signature = request.signature ?? "0x";
|
|
24117
|
+
if (request.sessionKey && !request.signature) {
|
|
24118
|
+
const keyHash = keccak256(
|
|
24119
|
+
encodeAbiParameters(parseAbiParameters("uint8, bytes32"), [
|
|
24120
|
+
0,
|
|
24121
|
+
// secp256k1
|
|
24122
|
+
keccak256(request.sessionKey)
|
|
24123
|
+
])
|
|
24124
|
+
);
|
|
24125
|
+
signature = concat([`0x${"00".repeat(65)}`, keyHash, "0x00"]);
|
|
24126
|
+
}
|
|
24140
24127
|
const intent = {
|
|
24141
24128
|
eoa: request.eoa,
|
|
24142
24129
|
executionData,
|
|
@@ -24149,14 +24136,14 @@ var RelayerService = class {
|
|
|
24149
24136
|
encodedPreCalls: request.encodedPreCalls ?? [],
|
|
24150
24137
|
encodedFundTransfers: request.encodedFundTransfers ?? [],
|
|
24151
24138
|
settler: request.settler ?? zeroAddress,
|
|
24152
|
-
expiry
|
|
24139
|
+
expiry,
|
|
24153
24140
|
isMultichain: request.isMultichain ?? false,
|
|
24154
24141
|
funder: request.funder ?? zeroAddress,
|
|
24155
24142
|
funderSignature: request.funderSignature ?? "0x",
|
|
24156
24143
|
settlerContext: request.settlerContext ?? "0x",
|
|
24157
24144
|
paymentAmount: BigInt(request.paymentAmount ?? "0"),
|
|
24158
24145
|
paymentRecipient: request.paymentRecipient ?? zeroAddress,
|
|
24159
|
-
signature
|
|
24146
|
+
signature,
|
|
24160
24147
|
paymentSignature: request.paymentSignature ?? "0x",
|
|
24161
24148
|
supportedAccountImplementation: request.supportedAccountImplementation ?? zeroAddress
|
|
24162
24149
|
};
|
|
@@ -24270,10 +24257,15 @@ var RelayerService = class {
|
|
|
24270
24257
|
request.prepareKey
|
|
24271
24258
|
);
|
|
24272
24259
|
if (!nonceResult.success) {
|
|
24273
|
-
return {
|
|
24260
|
+
return {
|
|
24261
|
+
success: false,
|
|
24262
|
+
error: nonceResult.error,
|
|
24263
|
+
conflictDraftId: nonceResult.conflictDraftId
|
|
24264
|
+
};
|
|
24274
24265
|
}
|
|
24275
24266
|
const nonce = nonceResult.nonce;
|
|
24276
|
-
const
|
|
24267
|
+
const nowSeconds = BigInt(Math.floor(Date.now() / 1e3));
|
|
24268
|
+
const expiry = resolveIntentExpirySeconds(request.expiry, nowSeconds);
|
|
24277
24269
|
const encodedPreCalls = request.encodedPreCalls ?? [];
|
|
24278
24270
|
const encodedFundTransfers = request.encodedFundTransfers ?? [];
|
|
24279
24271
|
const settler = request.settler ?? zeroAddress;
|
|
@@ -24281,11 +24273,7 @@ var RelayerService = class {
|
|
|
24281
24273
|
const paymentToken = request.paymentToken ?? zeroAddress;
|
|
24282
24274
|
const paymentMaxAmount = BigInt(request.paymentMaxAmount ?? "0");
|
|
24283
24275
|
const paymentEnabled = isPaymentEnabled(payer, paymentToken);
|
|
24284
|
-
const calls = request.calls
|
|
24285
|
-
to: c2.to,
|
|
24286
|
-
value: c2.value ? BigInt(c2.value) : 0n,
|
|
24287
|
-
data: c2.data ?? "0x"
|
|
24288
|
-
}));
|
|
24276
|
+
const calls = normalizeCalls(request.calls);
|
|
24289
24277
|
const simulateResult = await this.simulateIntent({
|
|
24290
24278
|
eoa: request.eoa,
|
|
24291
24279
|
calls: request.calls,
|
|
@@ -24296,7 +24284,8 @@ var RelayerService = class {
|
|
|
24296
24284
|
settler: request.settler,
|
|
24297
24285
|
payer: request.payer,
|
|
24298
24286
|
paymentToken: request.paymentToken,
|
|
24299
|
-
paymentMaxAmount: request.paymentMaxAmount
|
|
24287
|
+
paymentMaxAmount: request.paymentMaxAmount,
|
|
24288
|
+
sessionKey: request.sessionKey
|
|
24300
24289
|
});
|
|
24301
24290
|
const simulationGas = simulateResult.gasUsed ? BigInt(simulateResult.gasUsed) : 0n;
|
|
24302
24291
|
const simulationSucceeded = simulateResult.success && simulationGas > 0n;
|
|
@@ -24557,30 +24546,9 @@ function hashQuotes(signedQuotes, config2) {
|
|
|
24557
24546
|
settler: quote.intent.settler ?? zeroAddress,
|
|
24558
24547
|
expiry: BigInt(quote.intent.expiry || "0")
|
|
24559
24548
|
};
|
|
24560
|
-
const INTENT_TYPES_FOR_HASH = {
|
|
24561
|
-
Intent: [
|
|
24562
|
-
{ name: "multichain", type: "bool" },
|
|
24563
|
-
{ name: "eoa", type: "address" },
|
|
24564
|
-
{ name: "calls", type: "Call[]" },
|
|
24565
|
-
{ name: "nonce", type: "uint256" },
|
|
24566
|
-
{ name: "payer", type: "address" },
|
|
24567
|
-
{ name: "paymentToken", type: "address" },
|
|
24568
|
-
{ name: "paymentMaxAmount", type: "uint256" },
|
|
24569
|
-
{ name: "combinedGas", type: "uint256" },
|
|
24570
|
-
{ name: "encodedPreCalls", type: "bytes[]" },
|
|
24571
|
-
{ name: "encodedFundTransfers", type: "bytes[]" },
|
|
24572
|
-
{ name: "settler", type: "address" },
|
|
24573
|
-
{ name: "expiry", type: "uint256" }
|
|
24574
|
-
],
|
|
24575
|
-
Call: [
|
|
24576
|
-
{ name: "to", type: "address" },
|
|
24577
|
-
{ name: "value", type: "uint256" },
|
|
24578
|
-
{ name: "data", type: "bytes" }
|
|
24579
|
-
]
|
|
24580
|
-
};
|
|
24581
24549
|
const intentDigest = hashTypedData({
|
|
24582
24550
|
domain: domain2,
|
|
24583
|
-
types:
|
|
24551
|
+
types: INTENT_TYPES,
|
|
24584
24552
|
primaryType: "Intent",
|
|
24585
24553
|
message: intentMessage
|
|
24586
24554
|
});
|
|
@@ -24637,7 +24605,7 @@ function extractIntentFromContext(context) {
|
|
|
24637
24605
|
__name(extractIntentFromContext, "extractIntentFromContext");
|
|
24638
24606
|
async function validateQuote(signedQuotes, env) {
|
|
24639
24607
|
const currentTime = Math.floor(Date.now() / 1e3);
|
|
24640
|
-
if (typeof signedQuotes.ttl !== "number" || signedQuotes.ttl
|
|
24608
|
+
if (typeof signedQuotes.ttl !== "number" || signedQuotes.ttl <= currentTime) {
|
|
24641
24609
|
return new RpcError2(
|
|
24642
24610
|
QUOTE_EXPIRED,
|
|
24643
24611
|
`Quote expired at ${signedQuotes.ttl}, current time is ${currentTime}`
|
|
@@ -40053,6 +40021,7 @@ async function handlePrepareCalls(params, ctx) {
|
|
|
40053
40021
|
const nonce = meta3?.nonce;
|
|
40054
40022
|
const seqKey = meta3?.seq_key;
|
|
40055
40023
|
const prepareKey = meta3?.prepare_key;
|
|
40024
|
+
const expiry = meta3?.expiry;
|
|
40056
40025
|
const payer = meta3?.fee_payer;
|
|
40057
40026
|
const paymentToken = meta3?.fee_token;
|
|
40058
40027
|
const paymentMaxAmount = meta3?.fee_max_amount;
|
|
@@ -40071,13 +40040,27 @@ async function handlePrepareCalls(params, ctx) {
|
|
|
40071
40040
|
calls: normalizedCalls,
|
|
40072
40041
|
nonce,
|
|
40073
40042
|
seqKey,
|
|
40043
|
+
expiry,
|
|
40074
40044
|
settler,
|
|
40075
40045
|
payer,
|
|
40076
40046
|
paymentToken,
|
|
40077
40047
|
paymentMaxAmount,
|
|
40078
|
-
prepareKey
|
|
40048
|
+
prepareKey,
|
|
40049
|
+
sessionKey: typedParams.session_key
|
|
40079
40050
|
});
|
|
40080
40051
|
if (!result.success || !result.typedData || !result.digest) {
|
|
40052
|
+
if (result.conflictDraftId) {
|
|
40053
|
+
throw new RpcError2(DRAFT_CONFLICT, result.error ?? "Draft conflict", {
|
|
40054
|
+
conflictDraftId: result.conflictDraftId
|
|
40055
|
+
});
|
|
40056
|
+
}
|
|
40057
|
+
const rawError = result.error ?? "Failed to prepare calls";
|
|
40058
|
+
if (rawError.toLowerCase().startsWith("simulation failed")) {
|
|
40059
|
+
const cause = rawError.replace(/^simulation failed:\s*/i, "").trim();
|
|
40060
|
+
throw new RpcError2(SIMULATION_FAILED, "Simulation failed", {
|
|
40061
|
+
cause: cause.length > 0 ? cause : void 0
|
|
40062
|
+
});
|
|
40063
|
+
}
|
|
40081
40064
|
throw new RpcError2(INTERNAL_ERROR, result.error ?? "Failed to prepare calls");
|
|
40082
40065
|
}
|
|
40083
40066
|
const feeConfig = getFeeConfig(env);
|
|
@@ -40212,14 +40195,6 @@ async function handlePrepareCalls(params, ctx) {
|
|
|
40212
40195
|
message[key] = value;
|
|
40213
40196
|
}
|
|
40214
40197
|
}
|
|
40215
|
-
let callKey;
|
|
40216
|
-
if (typedParams.key) {
|
|
40217
|
-
callKey = {
|
|
40218
|
-
type: typedParams.key.type,
|
|
40219
|
-
publicKey: typedParams.key.public_key,
|
|
40220
|
-
prehash: typedParams.key.prehash ?? false
|
|
40221
|
-
};
|
|
40222
|
-
}
|
|
40223
40198
|
return {
|
|
40224
40199
|
context: preparedContext,
|
|
40225
40200
|
digest: result.digest,
|
|
@@ -40235,7 +40210,6 @@ async function handlePrepareCalls(params, ctx) {
|
|
|
40235
40210
|
feeTotals: {},
|
|
40236
40211
|
assetDiffs: {}
|
|
40237
40212
|
},
|
|
40238
|
-
key: callKey,
|
|
40239
40213
|
signature: signedQuotes.signature
|
|
40240
40214
|
};
|
|
40241
40215
|
}
|
|
@@ -45439,11 +45413,17 @@ __name(isPendingTransactionIdUniqueConstraintError, "isPendingTransactionIdUniqu
|
|
|
45439
45413
|
|
|
45440
45414
|
// src/durable-objects/signer.do.ts
|
|
45441
45415
|
var DEFAULT_MAX_PENDING = 16;
|
|
45442
|
-
var BALANCE_CHECK_INTERVAL_MS =
|
|
45416
|
+
var BALANCE_CHECK_INTERVAL_MS = 3e5;
|
|
45443
45417
|
var STALE_TX_THRESHOLD_MS = 5 * 60 * 1e3;
|
|
45444
45418
|
var DEFAULT_INTENT_EXPIRY_BUFFER_SECONDS = 30;
|
|
45445
45419
|
var DUPLICATE_TX_WAIT_MS = 2e3;
|
|
45446
45420
|
var DUPLICATE_TX_WAIT_POLL_MS = 100;
|
|
45421
|
+
function mapStoredTxStatusToPublicStatus(storedStatus) {
|
|
45422
|
+
if (storedStatus === "confirmed") return "confirmed";
|
|
45423
|
+
if (storedStatus === "failed" || storedStatus === "stuck") return "failed";
|
|
45424
|
+
return "pending";
|
|
45425
|
+
}
|
|
45426
|
+
__name(mapStoredTxStatusToPublicStatus, "mapStoredTxStatusToPublicStatus");
|
|
45447
45427
|
function isIntentExpired(expiryTimestamp, bufferSeconds = DEFAULT_INTENT_EXPIRY_BUFFER_SECONDS) {
|
|
45448
45428
|
const expiry = typeof expiryTimestamp === "string" ? BigInt(expiryTimestamp) : expiryTimestamp;
|
|
45449
45429
|
const currentTime = BigInt(Math.floor(Date.now() / 1e3));
|
|
@@ -45878,11 +45858,12 @@ var SignerDO = class extends DurableObject {
|
|
|
45878
45858
|
}
|
|
45879
45859
|
} catch {
|
|
45880
45860
|
}
|
|
45861
|
+
const fallbackStatus = mapStoredTxStatusToPublicStatus(status);
|
|
45881
45862
|
return {
|
|
45882
45863
|
txId,
|
|
45883
45864
|
txHash,
|
|
45884
45865
|
chainId,
|
|
45885
|
-
status:
|
|
45866
|
+
status: fallbackStatus,
|
|
45886
45867
|
submittedAt: sentAt
|
|
45887
45868
|
};
|
|
45888
45869
|
}
|
|
@@ -45954,7 +45935,7 @@ var SignerDO = class extends DurableObject {
|
|
|
45954
45935
|
await this.ensureInitialized();
|
|
45955
45936
|
const rows = this.sql.exec(
|
|
45956
45937
|
`
|
|
45957
|
-
SELECT address, paused, last_balance_check, balance_wei
|
|
45938
|
+
SELECT address, chain_id, paused, last_balance_check, balance_wei
|
|
45958
45939
|
FROM signer_state WHERE id = 1
|
|
45959
45940
|
`
|
|
45960
45941
|
).toArray();
|
|
@@ -47754,6 +47735,15 @@ var IntentNonceDO = class extends DurableObject4 {
|
|
|
47754
47735
|
draftKey,
|
|
47755
47736
|
draftTtlMs: coerceDraftTtlMs(draftTtlMs)
|
|
47756
47737
|
});
|
|
47738
|
+
if ("error" in result) {
|
|
47739
|
+
return Response.json(
|
|
47740
|
+
{
|
|
47741
|
+
error: result.error,
|
|
47742
|
+
conflictDraftId: result.conflictDraftId
|
|
47743
|
+
},
|
|
47744
|
+
{ status: 409 }
|
|
47745
|
+
);
|
|
47746
|
+
}
|
|
47757
47747
|
return Response.json({
|
|
47758
47748
|
nonce: result.nonce.toString(),
|
|
47759
47749
|
draftId: result.draftId,
|
|
@@ -47935,6 +47925,14 @@ var IntentNonceDO = class extends DurableObject4 {
|
|
|
47935
47925
|
this.deleteExpiredDraftForSeqKey(key, nowMs);
|
|
47936
47926
|
const existingDraft = this.getDraftForSeqKey(key);
|
|
47937
47927
|
if (existingDraft !== null) {
|
|
47928
|
+
const incomingDraftKey = options.draftKey ?? null;
|
|
47929
|
+
const existingDraftKey = existingDraft.draft_key;
|
|
47930
|
+
if (incomingDraftKey !== existingDraftKey) {
|
|
47931
|
+
return {
|
|
47932
|
+
error: "draft already exists for seqKey with a different draftKey; complete or cancel the active request first",
|
|
47933
|
+
conflictDraftId: existingDraft.draft_id
|
|
47934
|
+
};
|
|
47935
|
+
}
|
|
47938
47936
|
return {
|
|
47939
47937
|
nonce: BigInt(existingDraft.nonce),
|
|
47940
47938
|
draftId: existingDraft.draft_id,
|