@rhea-finance/cross-chain-aggregation-dex 1.0.6 → 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/README.md +277 -270
- package/dist/executors/aptos.d.mts +19 -0
- package/dist/executors/aptos.d.ts +19 -0
- package/dist/executors/aptos.js +140 -0
- package/dist/executors/aptos.js.map +1 -0
- package/dist/executors/aptos.mjs +138 -0
- package/dist/executors/aptos.mjs.map +1 -0
- package/dist/executors/bitcoin.d.mts +22 -0
- package/dist/executors/bitcoin.d.ts +22 -0
- package/dist/executors/bitcoin.js +153 -0
- package/dist/executors/bitcoin.js.map +1 -0
- package/dist/executors/bitcoin.mjs +151 -0
- package/dist/executors/bitcoin.mjs.map +1 -0
- package/dist/executors/evm.d.mts +18 -0
- package/dist/executors/evm.d.ts +18 -0
- package/dist/executors/evm.js +233 -0
- package/dist/executors/evm.js.map +1 -0
- package/dist/executors/evm.mjs +231 -0
- package/dist/executors/evm.mjs.map +1 -0
- package/dist/executors/near.d.mts +18 -0
- package/dist/executors/near.d.ts +18 -0
- package/dist/executors/near.js +162 -0
- package/dist/executors/near.js.map +1 -0
- package/dist/executors/near.mjs +160 -0
- package/dist/executors/near.mjs.map +1 -0
- package/dist/executors/solana.d.mts +20 -0
- package/dist/executors/solana.d.ts +20 -0
- package/dist/executors/solana.js +151 -0
- package/dist/executors/solana.js.map +1 -0
- package/dist/executors/solana.mjs +149 -0
- package/dist/executors/solana.mjs.map +1 -0
- package/dist/executors/sui.d.mts +19 -0
- package/dist/executors/sui.d.ts +19 -0
- package/dist/executors/sui.js +154 -0
- package/dist/executors/sui.js.map +1 -0
- package/dist/executors/sui.mjs +152 -0
- package/dist/executors/sui.mjs.map +1 -0
- package/dist/executors/tron.d.mts +24 -0
- package/dist/executors/tron.d.ts +24 -0
- package/dist/executors/tron.js +161 -0
- package/dist/executors/tron.js.map +1 -0
- package/dist/executors/tron.mjs +159 -0
- package/dist/executors/tron.mjs.map +1 -0
- package/dist/executors/zcash.d.mts +19 -0
- package/dist/executors/zcash.d.ts +19 -0
- package/dist/executors/zcash.js +158 -0
- package/dist/executors/zcash.js.map +1 -0
- package/dist/executors/zcash.mjs +156 -0
- package/dist/executors/zcash.mjs.map +1 -0
- package/dist/index.d.mts +278 -250
- package/dist/index.d.ts +278 -250
- package/dist/index.js +2369 -573
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2340 -560
- package/dist/index.mjs.map +1 -1
- package/dist/registry-DRYUqs7T.d.mts +532 -0
- package/dist/registry-DRYUqs7T.d.ts +532 -0
- package/dist/shared-BdH3hWuP.d.ts +23 -0
- package/dist/shared-BqpFeosz.d.mts +23 -0
- package/package.json +51 -17
|
@@ -0,0 +1,231 @@
|
|
|
1
|
+
// src/core/errors.ts
|
|
2
|
+
var SwapSdkError = class extends Error {
|
|
3
|
+
constructor(code, stage, message, options = {}) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.stage = stage;
|
|
7
|
+
this.options = options;
|
|
8
|
+
this.name = "SwapSdkError";
|
|
9
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
10
|
+
}
|
|
11
|
+
get retryable() {
|
|
12
|
+
return this.options.retryable ?? false;
|
|
13
|
+
}
|
|
14
|
+
get cause() {
|
|
15
|
+
return this.options.cause;
|
|
16
|
+
}
|
|
17
|
+
get details() {
|
|
18
|
+
return this.options.details;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// src/executors/shared.ts
|
|
23
|
+
function exposeExecutorSigner(signerChain, adapter) {
|
|
24
|
+
return {
|
|
25
|
+
signerChain,
|
|
26
|
+
...adapter.getIdentityKey ? { getIdentityKey: () => adapter.getIdentityKey() } : {},
|
|
27
|
+
...adapter.signMessage ? {
|
|
28
|
+
signMessage: (message, options) => adapter.signMessage(message, options)
|
|
29
|
+
} : {}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function throwIfAborted(signal, stage = "sign") {
|
|
33
|
+
if (!signal?.aborted) return;
|
|
34
|
+
throw new SwapSdkError("REQUEST_ABORTED", stage, "Execution was aborted", {
|
|
35
|
+
cause: signal.reason
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
async function requestSignApproval(context, chain, kind, summary) {
|
|
39
|
+
throwIfAborted(context.signal, "sign");
|
|
40
|
+
await context.beforeSign?.({ chain, kind, summary });
|
|
41
|
+
throwIfAborted(context.signal, "sign");
|
|
42
|
+
}
|
|
43
|
+
function mapExecutorError(error, adapter, stage, code, message) {
|
|
44
|
+
if (error instanceof SwapSdkError) return error;
|
|
45
|
+
if (isUserRejection(error, adapter)) {
|
|
46
|
+
return new SwapSdkError("USER_REJECTED", stage, "User rejected the request", {
|
|
47
|
+
cause: error
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
return new SwapSdkError(code, stage, message, { cause: error });
|
|
51
|
+
}
|
|
52
|
+
function isUserRejection(error, adapter) {
|
|
53
|
+
if (adapter.isUserRejection?.(error)) return true;
|
|
54
|
+
if (typeof error !== "object" || error === null) return false;
|
|
55
|
+
const code = "code" in error ? error.code : void 0;
|
|
56
|
+
if (code === 4001 || code === "ACTION_REJECTED") return true;
|
|
57
|
+
const message = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
58
|
+
return /user (rejected|denied)|request rejected|cancelled by user/.test(message);
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
// src/executors/evm/index.ts
|
|
62
|
+
function createEvmExecutor(adapter) {
|
|
63
|
+
return {
|
|
64
|
+
...exposeExecutorSigner("evm", adapter),
|
|
65
|
+
kinds: ["evm-transaction", "evm-signature"],
|
|
66
|
+
async validate(execution, context) {
|
|
67
|
+
throwIfAborted(context.signal, "sign");
|
|
68
|
+
if (execution.kind === "evm-signature") {
|
|
69
|
+
const expectedChainId = execution.request.chainId;
|
|
70
|
+
const domainChainId = execution.request.typedData.domain.chainId;
|
|
71
|
+
if (domainChainId !== void 0 && String(domainChainId) !== String(expectedChainId)) {
|
|
72
|
+
throw new SwapSdkError(
|
|
73
|
+
"CHAIN_MISMATCH",
|
|
74
|
+
"sign",
|
|
75
|
+
`EIP-712 domain chain ${String(domainChainId)} does not match request chain ${expectedChainId}`
|
|
76
|
+
);
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
},
|
|
80
|
+
async execute(execution, context) {
|
|
81
|
+
return execution.kind === "evm-signature" ? executeSignature(adapter, execution, context) : executeTransaction(adapter, execution, context);
|
|
82
|
+
}
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
async function executeSignature(adapter, execution, context) {
|
|
86
|
+
await executeApprovalIfRequired(adapter, execution, context);
|
|
87
|
+
await requestSignApproval(context, execution.chain, execution.kind, {
|
|
88
|
+
router: execution.request.router,
|
|
89
|
+
quoteId: execution.request.quoteId,
|
|
90
|
+
primaryType: execution.request.typedData.primaryType
|
|
91
|
+
});
|
|
92
|
+
try {
|
|
93
|
+
const signature = await adapter.signTypedData(execution.request, {
|
|
94
|
+
signal: context.signal
|
|
95
|
+
});
|
|
96
|
+
throwIfAborted(context.signal, "sign");
|
|
97
|
+
if (!signature) {
|
|
98
|
+
throw new SwapSdkError(
|
|
99
|
+
"SIGNING_FAILED",
|
|
100
|
+
"sign",
|
|
101
|
+
"EVM wallet returned an empty signature"
|
|
102
|
+
);
|
|
103
|
+
}
|
|
104
|
+
return {
|
|
105
|
+
status: "submitted",
|
|
106
|
+
signature,
|
|
107
|
+
...execution.request.signingScheme ? { signingScheme: execution.request.signingScheme } : {}
|
|
108
|
+
};
|
|
109
|
+
} catch (error) {
|
|
110
|
+
throw mapExecutorError(
|
|
111
|
+
error,
|
|
112
|
+
adapter,
|
|
113
|
+
"sign",
|
|
114
|
+
"SIGNING_FAILED",
|
|
115
|
+
"Failed to sign EIP-712 order"
|
|
116
|
+
);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
async function executeTransaction(adapter, execution, context) {
|
|
120
|
+
await executeApprovalIfRequired(adapter, execution, context);
|
|
121
|
+
await requestSignApproval(context, execution.chain, execution.kind, {
|
|
122
|
+
to: execution.tx.to,
|
|
123
|
+
value: execution.tx.value,
|
|
124
|
+
chainId: execution.tx.chainId
|
|
125
|
+
});
|
|
126
|
+
let submission;
|
|
127
|
+
try {
|
|
128
|
+
submission = await adapter.sendTransaction(execution.tx, {
|
|
129
|
+
signal: context.signal
|
|
130
|
+
});
|
|
131
|
+
} catch (error) {
|
|
132
|
+
throw mapExecutorError(
|
|
133
|
+
error,
|
|
134
|
+
adapter,
|
|
135
|
+
"broadcast",
|
|
136
|
+
"BROADCAST_FAILED",
|
|
137
|
+
"Failed to broadcast EVM transaction"
|
|
138
|
+
);
|
|
139
|
+
}
|
|
140
|
+
return confirmIfRequested(adapter, submission, context);
|
|
141
|
+
}
|
|
142
|
+
async function executeApprovalIfRequired(adapter, execution, context) {
|
|
143
|
+
if (execution.approval) {
|
|
144
|
+
let approvalRequired;
|
|
145
|
+
try {
|
|
146
|
+
approvalRequired = adapter.isApprovalRequired ? await adapter.isApprovalRequired(execution.approval) : true;
|
|
147
|
+
} catch (error) {
|
|
148
|
+
throw mapExecutorError(
|
|
149
|
+
error,
|
|
150
|
+
adapter,
|
|
151
|
+
"approve",
|
|
152
|
+
"APPROVAL_FAILED",
|
|
153
|
+
"Failed to determine EVM approval requirement"
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
if (approvalRequired) {
|
|
157
|
+
await sendApproval(adapter, execution, execution.approval, context);
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
async function sendApproval(adapter, execution, approval, context) {
|
|
162
|
+
context.emit({
|
|
163
|
+
type: "approval-requested",
|
|
164
|
+
executionId: context.executionId
|
|
165
|
+
});
|
|
166
|
+
await requestSignApproval(context, execution.chain, "evm-approval", {
|
|
167
|
+
spender: approval.spender,
|
|
168
|
+
to: approval.tx.to
|
|
169
|
+
});
|
|
170
|
+
try {
|
|
171
|
+
const submission = await adapter.sendTransaction(approval.tx, {
|
|
172
|
+
signal: context.signal
|
|
173
|
+
});
|
|
174
|
+
context.emit({
|
|
175
|
+
type: "approval-submitted",
|
|
176
|
+
executionId: context.executionId,
|
|
177
|
+
txHash: submission.txHash
|
|
178
|
+
});
|
|
179
|
+
if (adapter.waitForTransaction) {
|
|
180
|
+
await adapter.waitForTransaction(submission.txHash, {
|
|
181
|
+
signal: context.signal
|
|
182
|
+
});
|
|
183
|
+
}
|
|
184
|
+
} catch (error) {
|
|
185
|
+
throw mapExecutorError(
|
|
186
|
+
error,
|
|
187
|
+
adapter,
|
|
188
|
+
"approve",
|
|
189
|
+
"APPROVAL_FAILED",
|
|
190
|
+
"Failed to approve EVM token"
|
|
191
|
+
);
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
async function confirmIfRequested(adapter, submission, context) {
|
|
195
|
+
if (context.waitFor === "submitted") {
|
|
196
|
+
return {
|
|
197
|
+
status: "submitted",
|
|
198
|
+
txHash: submission.txHash,
|
|
199
|
+
...submission.raw !== void 0 ? { raw: submission.raw } : {}
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
if (!adapter.waitForTransaction) {
|
|
203
|
+
return {
|
|
204
|
+
status: "submitted",
|
|
205
|
+
txHash: submission.txHash,
|
|
206
|
+
...submission.raw !== void 0 ? { raw: submission.raw } : {}
|
|
207
|
+
};
|
|
208
|
+
}
|
|
209
|
+
try {
|
|
210
|
+
const confirmation = await adapter.waitForTransaction(submission.txHash, {
|
|
211
|
+
signal: context.signal
|
|
212
|
+
});
|
|
213
|
+
return {
|
|
214
|
+
status: "source-confirmed",
|
|
215
|
+
txHash: submission.txHash,
|
|
216
|
+
raw: confirmation ?? submission.raw
|
|
217
|
+
};
|
|
218
|
+
} catch (error) {
|
|
219
|
+
throw mapExecutorError(
|
|
220
|
+
error,
|
|
221
|
+
adapter,
|
|
222
|
+
"broadcast",
|
|
223
|
+
"BROADCAST_FAILED",
|
|
224
|
+
"Failed while confirming EVM transaction"
|
|
225
|
+
);
|
|
226
|
+
}
|
|
227
|
+
}
|
|
228
|
+
|
|
229
|
+
export { createEvmExecutor };
|
|
230
|
+
//# sourceMappingURL=evm.mjs.map
|
|
231
|
+
//# sourceMappingURL=evm.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/errors.ts","../../src/executors/shared.ts","../../src/executors/evm/index.ts"],"names":[],"mappings":"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","file":"evm.mjs","sourcesContent":["export type SwapErrorCode =\n | \"HTTP_ERROR\"\n | \"API_ERROR\"\n | \"RATE_LIMITED\"\n | \"AUTH_FAILED\"\n | \"REQUEST_ABORTED\"\n | \"REQUEST_TIMEOUT\"\n | \"INVALID_REQUEST\"\n | \"INVALID_API_RESPONSE\"\n | \"QUOTE_EXPIRED\"\n | \"ROUTE_NOT_FOUND\"\n | \"EXECUTOR_NOT_FOUND\"\n | \"UNSUPPORTED_CHAIN\"\n | \"CHAIN_MISMATCH\"\n | \"INVALID_TRANSACTION\"\n | \"USER_REJECTED\"\n | \"INSUFFICIENT_BALANCE\"\n | \"APPROVAL_FAILED\"\n | \"SIGNING_FAILED\"\n | \"BROADCAST_FAILED\"\n | \"ORDER_SUBMIT_FAILED\"\n | \"ORDER_TIMEOUT\"\n | \"REPORT_FAILED\";\n\nexport type SwapErrorStage =\n | \"quote\"\n | \"build\"\n | \"approve\"\n | \"sign\"\n | \"broadcast\"\n | \"submit\"\n | \"report\"\n | \"status\"\n | \"history\";\n\nexport interface SwapSdkErrorOptions {\n retryable?: boolean;\n cause?: unknown;\n details?: Record<string, unknown>;\n}\n\nexport class SwapSdkError extends Error {\n readonly name = \"SwapSdkError\";\n\n constructor(\n readonly code: SwapErrorCode,\n readonly stage: SwapErrorStage,\n message: string,\n readonly options: SwapSdkErrorOptions = {}\n ) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n get retryable(): boolean {\n return this.options.retryable ?? false;\n }\n\n get cause(): unknown {\n return this.options.cause;\n }\n\n get details(): Record<string, unknown> | undefined {\n return this.options.details;\n }\n}\n\nexport function asSwapSdkError(\n error: unknown,\n stage: SwapErrorStage\n): SwapSdkError {\n if (error instanceof SwapSdkError) return error;\n\n const message = error instanceof Error ? error.message : String(error);\n return new SwapSdkError(\"API_ERROR\", stage, message, { cause: error });\n}\n","import {\n SwapSdkError,\n type SwapErrorCode,\n type SwapErrorStage,\n} from \"../core/errors\";\nimport type {\n ChainExecutor,\n ExecutionContext,\n MessageSignOptions,\n} from \"../core/registry\";\nimport type { ChainRef } from \"../types/chain\";\n\nexport interface TransactionSubmission {\n txHash: string;\n raw?: unknown;\n}\n\nexport interface TransferSubmission {\n txHash?: string;\n requiresUserAction?: boolean;\n raw?: unknown;\n}\n\nexport interface ExecutorErrorAdapter {\n isUserRejection?(error: unknown): boolean;\n /** Identity serialized as `mca.signer.identityKey` for MCA quotes. */\n getIdentityKey?(): string | Promise<string>;\n /**\n * Optional offline message signing for flows such as MCA relayer withdraw.\n * Chain transfer executors do not call this during normal swap execution.\n */\n signMessage?(\n message: string,\n options?: MessageSignOptions\n ): Promise<string>;\n}\n\nexport function exposeExecutorSigner(\n signerChain: string,\n adapter: ExecutorErrorAdapter\n): Pick<\n ChainExecutor,\n \"signerChain\" | \"getIdentityKey\" | \"signMessage\"\n> {\n return {\n signerChain,\n ...(adapter.getIdentityKey\n ? { getIdentityKey: () => adapter.getIdentityKey!() }\n : {}),\n ...(adapter.signMessage\n ? {\n signMessage: (\n message: string,\n options?: MessageSignOptions\n ) => adapter.signMessage!(message, options),\n }\n : {}),\n };\n}\n\nexport function throwIfAborted(\n signal: AbortSignal | undefined,\n stage: SwapErrorStage = \"sign\"\n): void {\n if (!signal?.aborted) return;\n throw new SwapSdkError(\"REQUEST_ABORTED\", stage, \"Execution was aborted\", {\n cause: signal.reason,\n });\n}\n\nexport function assertChain(\n expected: ChainRef,\n actual: ChainRef,\n stage: SwapErrorStage = \"sign\"\n): void {\n if (expected === actual) return;\n throw new SwapSdkError(\n \"CHAIN_MISMATCH\",\n stage,\n `Connected chain ${actual} does not match execution chain ${expected}`,\n { details: { expected, actual } }\n );\n}\n\nexport async function requestSignApproval(\n context: ExecutionContext,\n chain: ChainRef,\n kind: string,\n summary: Record<string, unknown>\n): Promise<void> {\n throwIfAborted(context.signal, \"sign\");\n await context.beforeSign?.({ chain, kind, summary });\n throwIfAborted(context.signal, \"sign\");\n}\n\nexport function mapExecutorError(\n error: unknown,\n adapter: ExecutorErrorAdapter,\n stage: SwapErrorStage,\n code: SwapErrorCode,\n message: string\n): SwapSdkError {\n if (error instanceof SwapSdkError) return error;\n if (isUserRejection(error, adapter)) {\n return new SwapSdkError(\"USER_REJECTED\", stage, \"User rejected the request\", {\n cause: error,\n });\n }\n return new SwapSdkError(code, stage, message, { cause: error });\n}\n\nfunction isUserRejection(\n error: unknown,\n adapter: ExecutorErrorAdapter\n): boolean {\n if (adapter.isUserRejection?.(error)) return true;\n if (typeof error !== \"object\" || error === null) return false;\n const code = \"code\" in error ? error.code : undefined;\n if (code === 4001 || code === \"ACTION_REJECTED\") return true;\n const message =\n \"message\" in error && typeof error.message === \"string\"\n ? error.message.toLowerCase()\n : \"\";\n return /user (rejected|denied)|request rejected|cancelled by user/.test(message);\n}\n","import { SwapSdkError } from \"../../core/errors\";\nimport type {\n ChainExecutionResult,\n ChainExecutor,\n ExecutionContext,\n} from \"../../core/registry\";\nimport type {\n EvmApproval,\n EvmSigningRequest,\n EvmTx,\n SwapExecution,\n} from \"../../types/execution\";\nimport {\n exposeExecutorSigner,\n mapExecutorError,\n requestSignApproval,\n throwIfAborted,\n type ExecutorErrorAdapter,\n type TransactionSubmission,\n} from \"../shared\";\n\ntype EvmExecution = Extract<\n SwapExecution,\n { kind: \"evm-transaction\" | \"evm-signature\" }\n>;\n\nexport interface EvmWalletAdapter extends ExecutorErrorAdapter {\n sendTransaction(\n tx: EvmTx,\n options: { signal?: AbortSignal }\n ): Promise<TransactionSubmission>;\n signTypedData(\n request: EvmSigningRequest,\n options: { signal?: AbortSignal }\n ): Promise<string>;\n isApprovalRequired?(approval: EvmApproval): boolean | Promise<boolean>;\n waitForTransaction?(\n txHash: string,\n options: { signal?: AbortSignal }\n ): Promise<unknown>;\n}\n\nexport function createEvmExecutor(\n adapter: EvmWalletAdapter\n): ChainExecutor<\"evm-transaction\" | \"evm-signature\"> {\n return {\n ...exposeExecutorSigner(\"evm\", adapter),\n kinds: [\"evm-transaction\", \"evm-signature\"],\n\n async validate(execution, context) {\n throwIfAborted(context.signal, \"sign\");\n if (execution.kind === \"evm-signature\") {\n const expectedChainId = execution.request.chainId;\n const domainChainId = execution.request.typedData.domain.chainId;\n if (\n domainChainId !== undefined &&\n String(domainChainId) !== String(expectedChainId)\n ) {\n throw new SwapSdkError(\n \"CHAIN_MISMATCH\",\n \"sign\",\n `EIP-712 domain chain ${String(domainChainId)} does not match request chain ${expectedChainId}`\n );\n }\n }\n },\n\n async execute(execution, context) {\n return execution.kind === \"evm-signature\"\n ? executeSignature(adapter, execution, context)\n : executeTransaction(adapter, execution, context);\n },\n };\n}\n\nasync function executeSignature(\n adapter: EvmWalletAdapter,\n execution: Extract<EvmExecution, { kind: \"evm-signature\" }>,\n context: ExecutionContext\n): Promise<ChainExecutionResult> {\n await executeApprovalIfRequired(adapter, execution, context);\n await requestSignApproval(context, execution.chain, execution.kind, {\n router: execution.request.router,\n quoteId: execution.request.quoteId,\n primaryType: execution.request.typedData.primaryType,\n });\n try {\n const signature = await adapter.signTypedData(execution.request, {\n signal: context.signal,\n });\n throwIfAborted(context.signal, \"sign\");\n if (!signature) {\n throw new SwapSdkError(\n \"SIGNING_FAILED\",\n \"sign\",\n \"EVM wallet returned an empty signature\"\n );\n }\n return {\n status: \"submitted\",\n signature,\n ...(execution.request.signingScheme\n ? { signingScheme: execution.request.signingScheme }\n : {}),\n };\n } catch (error) {\n throw mapExecutorError(\n error,\n adapter,\n \"sign\",\n \"SIGNING_FAILED\",\n \"Failed to sign EIP-712 order\"\n );\n }\n}\n\nasync function executeTransaction(\n adapter: EvmWalletAdapter,\n execution: Extract<EvmExecution, { kind: \"evm-transaction\" }>,\n context: ExecutionContext\n): Promise<ChainExecutionResult> {\n await executeApprovalIfRequired(adapter, execution, context);\n\n await requestSignApproval(context, execution.chain, execution.kind, {\n to: execution.tx.to,\n value: execution.tx.value,\n chainId: execution.tx.chainId,\n });\n let submission: TransactionSubmission;\n try {\n submission = await adapter.sendTransaction(execution.tx, {\n signal: context.signal,\n });\n } catch (error) {\n throw mapExecutorError(\n error,\n adapter,\n \"broadcast\",\n \"BROADCAST_FAILED\",\n \"Failed to broadcast EVM transaction\"\n );\n }\n\n return confirmIfRequested(adapter, submission, context);\n}\n\nasync function executeApprovalIfRequired(\n adapter: EvmWalletAdapter,\n execution: EvmExecution,\n context: ExecutionContext\n): Promise<void> {\n if (execution.approval) {\n let approvalRequired: boolean;\n try {\n approvalRequired = adapter.isApprovalRequired\n ? await adapter.isApprovalRequired(execution.approval)\n : true;\n } catch (error) {\n throw mapExecutorError(\n error,\n adapter,\n \"approve\",\n \"APPROVAL_FAILED\",\n \"Failed to determine EVM approval requirement\"\n );\n }\n if (approvalRequired) {\n await sendApproval(adapter, execution, execution.approval, context);\n }\n }\n}\n\nasync function sendApproval(\n adapter: EvmWalletAdapter,\n execution: EvmExecution,\n approval: EvmApproval,\n context: ExecutionContext\n): Promise<void> {\n context.emit({\n type: \"approval-requested\",\n executionId: context.executionId,\n });\n await requestSignApproval(context, execution.chain, \"evm-approval\", {\n spender: approval.spender,\n to: approval.tx.to,\n });\n try {\n const submission = await adapter.sendTransaction(approval.tx, {\n signal: context.signal,\n });\n context.emit({\n type: \"approval-submitted\",\n executionId: context.executionId,\n txHash: submission.txHash,\n });\n if (adapter.waitForTransaction) {\n await adapter.waitForTransaction(submission.txHash, {\n signal: context.signal,\n });\n }\n } catch (error) {\n throw mapExecutorError(\n error,\n adapter,\n \"approve\",\n \"APPROVAL_FAILED\",\n \"Failed to approve EVM token\"\n );\n }\n}\n\nasync function confirmIfRequested(\n adapter: EvmWalletAdapter,\n submission: TransactionSubmission,\n context: ExecutionContext\n): Promise<ChainExecutionResult> {\n if (context.waitFor === \"submitted\") {\n return {\n status: \"submitted\",\n txHash: submission.txHash,\n ...(submission.raw !== undefined ? { raw: submission.raw } : {}),\n };\n }\n if (!adapter.waitForTransaction) {\n return {\n status: \"submitted\",\n txHash: submission.txHash,\n ...(submission.raw !== undefined ? { raw: submission.raw } : {}),\n };\n }\n try {\n const confirmation = await adapter.waitForTransaction(submission.txHash, {\n signal: context.signal,\n });\n return {\n status: \"source-confirmed\",\n txHash: submission.txHash,\n raw: confirmation ?? submission.raw,\n };\n } catch (error) {\n throw mapExecutorError(\n error,\n adapter,\n \"broadcast\",\n \"BROADCAST_FAILED\",\n \"Failed while confirming EVM transaction\"\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { C as ChainRef, N as NearTransaction, q as ChainExecutor } from '../registry-DRYUqs7T.mjs';
|
|
2
|
+
import { E as ExecutorErrorAdapter } from '../shared-BqpFeosz.mjs';
|
|
3
|
+
|
|
4
|
+
interface NearWalletAdapter extends ExecutorErrorAdapter {
|
|
5
|
+
getChain(): ChainRef | Promise<ChainRef>;
|
|
6
|
+
signAndSendTransactions(transactions: NearTransaction[], options: {
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
}): Promise<{
|
|
9
|
+
txHashes: string[];
|
|
10
|
+
raw?: unknown;
|
|
11
|
+
}>;
|
|
12
|
+
waitForTransactions?(txHashes: string[], options: {
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
}): Promise<unknown>;
|
|
15
|
+
}
|
|
16
|
+
declare function createNearExecutor(adapter: NearWalletAdapter): ChainExecutor<"near-transaction-batch">;
|
|
17
|
+
|
|
18
|
+
export { type NearWalletAdapter, createNearExecutor };
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import { C as ChainRef, N as NearTransaction, q as ChainExecutor } from '../registry-DRYUqs7T.js';
|
|
2
|
+
import { E as ExecutorErrorAdapter } from '../shared-BdH3hWuP.js';
|
|
3
|
+
|
|
4
|
+
interface NearWalletAdapter extends ExecutorErrorAdapter {
|
|
5
|
+
getChain(): ChainRef | Promise<ChainRef>;
|
|
6
|
+
signAndSendTransactions(transactions: NearTransaction[], options: {
|
|
7
|
+
signal?: AbortSignal;
|
|
8
|
+
}): Promise<{
|
|
9
|
+
txHashes: string[];
|
|
10
|
+
raw?: unknown;
|
|
11
|
+
}>;
|
|
12
|
+
waitForTransactions?(txHashes: string[], options: {
|
|
13
|
+
signal?: AbortSignal;
|
|
14
|
+
}): Promise<unknown>;
|
|
15
|
+
}
|
|
16
|
+
declare function createNearExecutor(adapter: NearWalletAdapter): ChainExecutor<"near-transaction-batch">;
|
|
17
|
+
|
|
18
|
+
export { type NearWalletAdapter, createNearExecutor };
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
'use strict';
|
|
2
|
+
|
|
3
|
+
// src/core/errors.ts
|
|
4
|
+
var SwapSdkError = class extends Error {
|
|
5
|
+
constructor(code, stage, message, options = {}) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.stage = stage;
|
|
9
|
+
this.options = options;
|
|
10
|
+
this.name = "SwapSdkError";
|
|
11
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
12
|
+
}
|
|
13
|
+
get retryable() {
|
|
14
|
+
return this.options.retryable ?? false;
|
|
15
|
+
}
|
|
16
|
+
get cause() {
|
|
17
|
+
return this.options.cause;
|
|
18
|
+
}
|
|
19
|
+
get details() {
|
|
20
|
+
return this.options.details;
|
|
21
|
+
}
|
|
22
|
+
};
|
|
23
|
+
|
|
24
|
+
// src/executors/shared.ts
|
|
25
|
+
function exposeExecutorSigner(signerChain, adapter) {
|
|
26
|
+
return {
|
|
27
|
+
signerChain,
|
|
28
|
+
...adapter.getIdentityKey ? { getIdentityKey: () => adapter.getIdentityKey() } : {},
|
|
29
|
+
...adapter.signMessage ? {
|
|
30
|
+
signMessage: (message, options) => adapter.signMessage(message, options)
|
|
31
|
+
} : {}
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
function throwIfAborted(signal, stage = "sign") {
|
|
35
|
+
if (!signal?.aborted) return;
|
|
36
|
+
throw new SwapSdkError("REQUEST_ABORTED", stage, "Execution was aborted", {
|
|
37
|
+
cause: signal.reason
|
|
38
|
+
});
|
|
39
|
+
}
|
|
40
|
+
function assertChain(expected, actual, stage = "sign") {
|
|
41
|
+
if (expected === actual) return;
|
|
42
|
+
throw new SwapSdkError(
|
|
43
|
+
"CHAIN_MISMATCH",
|
|
44
|
+
stage,
|
|
45
|
+
`Connected chain ${actual} does not match execution chain ${expected}`,
|
|
46
|
+
{ details: { expected, actual } }
|
|
47
|
+
);
|
|
48
|
+
}
|
|
49
|
+
async function requestSignApproval(context, chain, kind, summary) {
|
|
50
|
+
throwIfAborted(context.signal, "sign");
|
|
51
|
+
await context.beforeSign?.({ chain, kind, summary });
|
|
52
|
+
throwIfAborted(context.signal, "sign");
|
|
53
|
+
}
|
|
54
|
+
function mapExecutorError(error, adapter, stage, code, message) {
|
|
55
|
+
if (error instanceof SwapSdkError) return error;
|
|
56
|
+
if (isUserRejection(error, adapter)) {
|
|
57
|
+
return new SwapSdkError("USER_REJECTED", stage, "User rejected the request", {
|
|
58
|
+
cause: error
|
|
59
|
+
});
|
|
60
|
+
}
|
|
61
|
+
return new SwapSdkError(code, stage, message, { cause: error });
|
|
62
|
+
}
|
|
63
|
+
function isUserRejection(error, adapter) {
|
|
64
|
+
if (adapter.isUserRejection?.(error)) return true;
|
|
65
|
+
if (typeof error !== "object" || error === null) return false;
|
|
66
|
+
const code = "code" in error ? error.code : void 0;
|
|
67
|
+
if (code === 4001 || code === "ACTION_REJECTED") return true;
|
|
68
|
+
const message = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
69
|
+
return /user (rejected|denied)|request rejected|cancelled by user/.test(message);
|
|
70
|
+
}
|
|
71
|
+
|
|
72
|
+
// src/executors/near/index.ts
|
|
73
|
+
function createNearExecutor(adapter) {
|
|
74
|
+
return {
|
|
75
|
+
...exposeExecutorSigner("near", adapter),
|
|
76
|
+
kinds: ["near-transaction-batch"],
|
|
77
|
+
async validate(execution, context) {
|
|
78
|
+
throwIfAborted(context.signal, "sign");
|
|
79
|
+
assertChain(execution.chain, await adapter.getChain());
|
|
80
|
+
if (execution.transactions.length === 0) {
|
|
81
|
+
throw new SwapSdkError(
|
|
82
|
+
"INVALID_TRANSACTION",
|
|
83
|
+
"sign",
|
|
84
|
+
"NEAR transaction batch cannot be empty"
|
|
85
|
+
);
|
|
86
|
+
}
|
|
87
|
+
for (const [index, transaction] of execution.transactions.entries()) {
|
|
88
|
+
if (!transaction.receiverId.trim() || transaction.actions.length === 0) {
|
|
89
|
+
throw new SwapSdkError(
|
|
90
|
+
"INVALID_TRANSACTION",
|
|
91
|
+
"sign",
|
|
92
|
+
`Invalid NEAR transaction at index ${index}`
|
|
93
|
+
);
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
},
|
|
97
|
+
async execute(execution, context) {
|
|
98
|
+
await requestSignApproval(context, execution.chain, execution.kind, {
|
|
99
|
+
transactionCount: execution.transactions.length,
|
|
100
|
+
receivers: execution.transactions.map((item) => item.receiverId)
|
|
101
|
+
});
|
|
102
|
+
let submission;
|
|
103
|
+
try {
|
|
104
|
+
submission = await adapter.signAndSendTransactions(
|
|
105
|
+
execution.transactions,
|
|
106
|
+
{ signal: context.signal }
|
|
107
|
+
);
|
|
108
|
+
} catch (error) {
|
|
109
|
+
throw mapExecutorError(
|
|
110
|
+
error,
|
|
111
|
+
adapter,
|
|
112
|
+
"broadcast",
|
|
113
|
+
"BROADCAST_FAILED",
|
|
114
|
+
"Failed to sign or broadcast NEAR transactions"
|
|
115
|
+
);
|
|
116
|
+
}
|
|
117
|
+
if (submission.txHashes.length === 0) {
|
|
118
|
+
throw new SwapSdkError(
|
|
119
|
+
"BROADCAST_FAILED",
|
|
120
|
+
"broadcast",
|
|
121
|
+
"NEAR wallet returned no transaction hashes"
|
|
122
|
+
);
|
|
123
|
+
}
|
|
124
|
+
return confirm(adapter, submission, context);
|
|
125
|
+
}
|
|
126
|
+
};
|
|
127
|
+
}
|
|
128
|
+
async function confirm(adapter, submission, context) {
|
|
129
|
+
const txHash = submission.txHashes[submission.txHashes.length - 1];
|
|
130
|
+
if (context.waitFor === "submitted" || !adapter.waitForTransactions) {
|
|
131
|
+
return {
|
|
132
|
+
status: "submitted",
|
|
133
|
+
txHash,
|
|
134
|
+
txHashes: submission.txHashes,
|
|
135
|
+
...submission.raw !== void 0 ? { raw: submission.raw } : {}
|
|
136
|
+
};
|
|
137
|
+
}
|
|
138
|
+
try {
|
|
139
|
+
const confirmation = await adapter.waitForTransactions(
|
|
140
|
+
submission.txHashes,
|
|
141
|
+
{ signal: context.signal }
|
|
142
|
+
);
|
|
143
|
+
return {
|
|
144
|
+
status: "source-confirmed",
|
|
145
|
+
txHash,
|
|
146
|
+
txHashes: submission.txHashes,
|
|
147
|
+
raw: confirmation ?? submission.raw
|
|
148
|
+
};
|
|
149
|
+
} catch (error) {
|
|
150
|
+
throw mapExecutorError(
|
|
151
|
+
error,
|
|
152
|
+
adapter,
|
|
153
|
+
"broadcast",
|
|
154
|
+
"BROADCAST_FAILED",
|
|
155
|
+
"Failed while confirming NEAR transactions"
|
|
156
|
+
);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
exports.createNearExecutor = createNearExecutor;
|
|
161
|
+
//# sourceMappingURL=near.js.map
|
|
162
|
+
//# sourceMappingURL=near.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/core/errors.ts","../../src/executors/shared.ts","../../src/executors/near/index.ts"],"names":[],"mappings":"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","file":"near.js","sourcesContent":["export type SwapErrorCode =\n | \"HTTP_ERROR\"\n | \"API_ERROR\"\n | \"RATE_LIMITED\"\n | \"AUTH_FAILED\"\n | \"REQUEST_ABORTED\"\n | \"REQUEST_TIMEOUT\"\n | \"INVALID_REQUEST\"\n | \"INVALID_API_RESPONSE\"\n | \"QUOTE_EXPIRED\"\n | \"ROUTE_NOT_FOUND\"\n | \"EXECUTOR_NOT_FOUND\"\n | \"UNSUPPORTED_CHAIN\"\n | \"CHAIN_MISMATCH\"\n | \"INVALID_TRANSACTION\"\n | \"USER_REJECTED\"\n | \"INSUFFICIENT_BALANCE\"\n | \"APPROVAL_FAILED\"\n | \"SIGNING_FAILED\"\n | \"BROADCAST_FAILED\"\n | \"ORDER_SUBMIT_FAILED\"\n | \"ORDER_TIMEOUT\"\n | \"REPORT_FAILED\";\n\nexport type SwapErrorStage =\n | \"quote\"\n | \"build\"\n | \"approve\"\n | \"sign\"\n | \"broadcast\"\n | \"submit\"\n | \"report\"\n | \"status\"\n | \"history\";\n\nexport interface SwapSdkErrorOptions {\n retryable?: boolean;\n cause?: unknown;\n details?: Record<string, unknown>;\n}\n\nexport class SwapSdkError extends Error {\n readonly name = \"SwapSdkError\";\n\n constructor(\n readonly code: SwapErrorCode,\n readonly stage: SwapErrorStage,\n message: string,\n readonly options: SwapSdkErrorOptions = {}\n ) {\n super(message);\n Object.setPrototypeOf(this, new.target.prototype);\n }\n\n get retryable(): boolean {\n return this.options.retryable ?? false;\n }\n\n get cause(): unknown {\n return this.options.cause;\n }\n\n get details(): Record<string, unknown> | undefined {\n return this.options.details;\n }\n}\n\nexport function asSwapSdkError(\n error: unknown,\n stage: SwapErrorStage\n): SwapSdkError {\n if (error instanceof SwapSdkError) return error;\n\n const message = error instanceof Error ? error.message : String(error);\n return new SwapSdkError(\"API_ERROR\", stage, message, { cause: error });\n}\n","import {\n SwapSdkError,\n type SwapErrorCode,\n type SwapErrorStage,\n} from \"../core/errors\";\nimport type {\n ChainExecutor,\n ExecutionContext,\n MessageSignOptions,\n} from \"../core/registry\";\nimport type { ChainRef } from \"../types/chain\";\n\nexport interface TransactionSubmission {\n txHash: string;\n raw?: unknown;\n}\n\nexport interface TransferSubmission {\n txHash?: string;\n requiresUserAction?: boolean;\n raw?: unknown;\n}\n\nexport interface ExecutorErrorAdapter {\n isUserRejection?(error: unknown): boolean;\n /** Identity serialized as `mca.signer.identityKey` for MCA quotes. */\n getIdentityKey?(): string | Promise<string>;\n /**\n * Optional offline message signing for flows such as MCA relayer withdraw.\n * Chain transfer executors do not call this during normal swap execution.\n */\n signMessage?(\n message: string,\n options?: MessageSignOptions\n ): Promise<string>;\n}\n\nexport function exposeExecutorSigner(\n signerChain: string,\n adapter: ExecutorErrorAdapter\n): Pick<\n ChainExecutor,\n \"signerChain\" | \"getIdentityKey\" | \"signMessage\"\n> {\n return {\n signerChain,\n ...(adapter.getIdentityKey\n ? { getIdentityKey: () => adapter.getIdentityKey!() }\n : {}),\n ...(adapter.signMessage\n ? {\n signMessage: (\n message: string,\n options?: MessageSignOptions\n ) => adapter.signMessage!(message, options),\n }\n : {}),\n };\n}\n\nexport function throwIfAborted(\n signal: AbortSignal | undefined,\n stage: SwapErrorStage = \"sign\"\n): void {\n if (!signal?.aborted) return;\n throw new SwapSdkError(\"REQUEST_ABORTED\", stage, \"Execution was aborted\", {\n cause: signal.reason,\n });\n}\n\nexport function assertChain(\n expected: ChainRef,\n actual: ChainRef,\n stage: SwapErrorStage = \"sign\"\n): void {\n if (expected === actual) return;\n throw new SwapSdkError(\n \"CHAIN_MISMATCH\",\n stage,\n `Connected chain ${actual} does not match execution chain ${expected}`,\n { details: { expected, actual } }\n );\n}\n\nexport async function requestSignApproval(\n context: ExecutionContext,\n chain: ChainRef,\n kind: string,\n summary: Record<string, unknown>\n): Promise<void> {\n throwIfAborted(context.signal, \"sign\");\n await context.beforeSign?.({ chain, kind, summary });\n throwIfAborted(context.signal, \"sign\");\n}\n\nexport function mapExecutorError(\n error: unknown,\n adapter: ExecutorErrorAdapter,\n stage: SwapErrorStage,\n code: SwapErrorCode,\n message: string\n): SwapSdkError {\n if (error instanceof SwapSdkError) return error;\n if (isUserRejection(error, adapter)) {\n return new SwapSdkError(\"USER_REJECTED\", stage, \"User rejected the request\", {\n cause: error,\n });\n }\n return new SwapSdkError(code, stage, message, { cause: error });\n}\n\nfunction isUserRejection(\n error: unknown,\n adapter: ExecutorErrorAdapter\n): boolean {\n if (adapter.isUserRejection?.(error)) return true;\n if (typeof error !== \"object\" || error === null) return false;\n const code = \"code\" in error ? error.code : undefined;\n if (code === 4001 || code === \"ACTION_REJECTED\") return true;\n const message =\n \"message\" in error && typeof error.message === \"string\"\n ? error.message.toLowerCase()\n : \"\";\n return /user (rejected|denied)|request rejected|cancelled by user/.test(message);\n}\n","import { SwapSdkError } from \"../../core/errors\";\nimport type {\n ChainExecutionResult,\n ChainExecutor,\n ExecutionContext,\n} from \"../../core/registry\";\nimport type { ChainRef } from \"../../types/chain\";\nimport type { NearTransaction } from \"../../types/execution\";\nimport {\n assertChain,\n exposeExecutorSigner,\n mapExecutorError,\n requestSignApproval,\n throwIfAborted,\n type ExecutorErrorAdapter,\n} from \"../shared\";\n\nexport interface NearWalletAdapter extends ExecutorErrorAdapter {\n getChain(): ChainRef | Promise<ChainRef>;\n signAndSendTransactions(\n transactions: NearTransaction[],\n options: { signal?: AbortSignal }\n ): Promise<{ txHashes: string[]; raw?: unknown }>;\n waitForTransactions?(\n txHashes: string[],\n options: { signal?: AbortSignal }\n ): Promise<unknown>;\n}\n\nexport function createNearExecutor(\n adapter: NearWalletAdapter\n): ChainExecutor<\"near-transaction-batch\"> {\n return {\n ...exposeExecutorSigner(\"near\", adapter),\n kinds: [\"near-transaction-batch\"],\n\n async validate(execution, context) {\n throwIfAborted(context.signal, \"sign\");\n assertChain(execution.chain, await adapter.getChain());\n if (execution.transactions.length === 0) {\n throw new SwapSdkError(\n \"INVALID_TRANSACTION\",\n \"sign\",\n \"NEAR transaction batch cannot be empty\"\n );\n }\n for (const [index, transaction] of execution.transactions.entries()) {\n if (!transaction.receiverId.trim() || transaction.actions.length === 0) {\n throw new SwapSdkError(\n \"INVALID_TRANSACTION\",\n \"sign\",\n `Invalid NEAR transaction at index ${index}`\n );\n }\n }\n },\n\n async execute(execution, context) {\n await requestSignApproval(context, execution.chain, execution.kind, {\n transactionCount: execution.transactions.length,\n receivers: execution.transactions.map((item) => item.receiverId),\n });\n let submission: { txHashes: string[]; raw?: unknown };\n try {\n submission = await adapter.signAndSendTransactions(\n execution.transactions,\n { signal: context.signal }\n );\n } catch (error) {\n throw mapExecutorError(\n error,\n adapter,\n \"broadcast\",\n \"BROADCAST_FAILED\",\n \"Failed to sign or broadcast NEAR transactions\"\n );\n }\n if (submission.txHashes.length === 0) {\n throw new SwapSdkError(\n \"BROADCAST_FAILED\",\n \"broadcast\",\n \"NEAR wallet returned no transaction hashes\"\n );\n }\n return confirm(adapter, submission, context);\n },\n };\n}\n\nasync function confirm(\n adapter: NearWalletAdapter,\n submission: { txHashes: string[]; raw?: unknown },\n context: ExecutionContext\n): Promise<ChainExecutionResult> {\n const txHash = submission.txHashes[submission.txHashes.length - 1]!;\n if (context.waitFor === \"submitted\" || !adapter.waitForTransactions) {\n return {\n status: \"submitted\",\n txHash,\n txHashes: submission.txHashes,\n ...(submission.raw !== undefined ? { raw: submission.raw } : {}),\n };\n }\n try {\n const confirmation = await adapter.waitForTransactions(\n submission.txHashes,\n { signal: context.signal }\n );\n return {\n status: \"source-confirmed\",\n txHash,\n txHashes: submission.txHashes,\n raw: confirmation ?? submission.raw,\n };\n } catch (error) {\n throw mapExecutorError(\n error,\n adapter,\n \"broadcast\",\n \"BROADCAST_FAILED\",\n \"Failed while confirming NEAR transactions\"\n );\n }\n}\n"]}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
// src/core/errors.ts
|
|
2
|
+
var SwapSdkError = class extends Error {
|
|
3
|
+
constructor(code, stage, message, options = {}) {
|
|
4
|
+
super(message);
|
|
5
|
+
this.code = code;
|
|
6
|
+
this.stage = stage;
|
|
7
|
+
this.options = options;
|
|
8
|
+
this.name = "SwapSdkError";
|
|
9
|
+
Object.setPrototypeOf(this, new.target.prototype);
|
|
10
|
+
}
|
|
11
|
+
get retryable() {
|
|
12
|
+
return this.options.retryable ?? false;
|
|
13
|
+
}
|
|
14
|
+
get cause() {
|
|
15
|
+
return this.options.cause;
|
|
16
|
+
}
|
|
17
|
+
get details() {
|
|
18
|
+
return this.options.details;
|
|
19
|
+
}
|
|
20
|
+
};
|
|
21
|
+
|
|
22
|
+
// src/executors/shared.ts
|
|
23
|
+
function exposeExecutorSigner(signerChain, adapter) {
|
|
24
|
+
return {
|
|
25
|
+
signerChain,
|
|
26
|
+
...adapter.getIdentityKey ? { getIdentityKey: () => adapter.getIdentityKey() } : {},
|
|
27
|
+
...adapter.signMessage ? {
|
|
28
|
+
signMessage: (message, options) => adapter.signMessage(message, options)
|
|
29
|
+
} : {}
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
function throwIfAborted(signal, stage = "sign") {
|
|
33
|
+
if (!signal?.aborted) return;
|
|
34
|
+
throw new SwapSdkError("REQUEST_ABORTED", stage, "Execution was aborted", {
|
|
35
|
+
cause: signal.reason
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
function assertChain(expected, actual, stage = "sign") {
|
|
39
|
+
if (expected === actual) return;
|
|
40
|
+
throw new SwapSdkError(
|
|
41
|
+
"CHAIN_MISMATCH",
|
|
42
|
+
stage,
|
|
43
|
+
`Connected chain ${actual} does not match execution chain ${expected}`,
|
|
44
|
+
{ details: { expected, actual } }
|
|
45
|
+
);
|
|
46
|
+
}
|
|
47
|
+
async function requestSignApproval(context, chain, kind, summary) {
|
|
48
|
+
throwIfAborted(context.signal, "sign");
|
|
49
|
+
await context.beforeSign?.({ chain, kind, summary });
|
|
50
|
+
throwIfAborted(context.signal, "sign");
|
|
51
|
+
}
|
|
52
|
+
function mapExecutorError(error, adapter, stage, code, message) {
|
|
53
|
+
if (error instanceof SwapSdkError) return error;
|
|
54
|
+
if (isUserRejection(error, adapter)) {
|
|
55
|
+
return new SwapSdkError("USER_REJECTED", stage, "User rejected the request", {
|
|
56
|
+
cause: error
|
|
57
|
+
});
|
|
58
|
+
}
|
|
59
|
+
return new SwapSdkError(code, stage, message, { cause: error });
|
|
60
|
+
}
|
|
61
|
+
function isUserRejection(error, adapter) {
|
|
62
|
+
if (adapter.isUserRejection?.(error)) return true;
|
|
63
|
+
if (typeof error !== "object" || error === null) return false;
|
|
64
|
+
const code = "code" in error ? error.code : void 0;
|
|
65
|
+
if (code === 4001 || code === "ACTION_REJECTED") return true;
|
|
66
|
+
const message = "message" in error && typeof error.message === "string" ? error.message.toLowerCase() : "";
|
|
67
|
+
return /user (rejected|denied)|request rejected|cancelled by user/.test(message);
|
|
68
|
+
}
|
|
69
|
+
|
|
70
|
+
// src/executors/near/index.ts
|
|
71
|
+
function createNearExecutor(adapter) {
|
|
72
|
+
return {
|
|
73
|
+
...exposeExecutorSigner("near", adapter),
|
|
74
|
+
kinds: ["near-transaction-batch"],
|
|
75
|
+
async validate(execution, context) {
|
|
76
|
+
throwIfAborted(context.signal, "sign");
|
|
77
|
+
assertChain(execution.chain, await adapter.getChain());
|
|
78
|
+
if (execution.transactions.length === 0) {
|
|
79
|
+
throw new SwapSdkError(
|
|
80
|
+
"INVALID_TRANSACTION",
|
|
81
|
+
"sign",
|
|
82
|
+
"NEAR transaction batch cannot be empty"
|
|
83
|
+
);
|
|
84
|
+
}
|
|
85
|
+
for (const [index, transaction] of execution.transactions.entries()) {
|
|
86
|
+
if (!transaction.receiverId.trim() || transaction.actions.length === 0) {
|
|
87
|
+
throw new SwapSdkError(
|
|
88
|
+
"INVALID_TRANSACTION",
|
|
89
|
+
"sign",
|
|
90
|
+
`Invalid NEAR transaction at index ${index}`
|
|
91
|
+
);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
},
|
|
95
|
+
async execute(execution, context) {
|
|
96
|
+
await requestSignApproval(context, execution.chain, execution.kind, {
|
|
97
|
+
transactionCount: execution.transactions.length,
|
|
98
|
+
receivers: execution.transactions.map((item) => item.receiverId)
|
|
99
|
+
});
|
|
100
|
+
let submission;
|
|
101
|
+
try {
|
|
102
|
+
submission = await adapter.signAndSendTransactions(
|
|
103
|
+
execution.transactions,
|
|
104
|
+
{ signal: context.signal }
|
|
105
|
+
);
|
|
106
|
+
} catch (error) {
|
|
107
|
+
throw mapExecutorError(
|
|
108
|
+
error,
|
|
109
|
+
adapter,
|
|
110
|
+
"broadcast",
|
|
111
|
+
"BROADCAST_FAILED",
|
|
112
|
+
"Failed to sign or broadcast NEAR transactions"
|
|
113
|
+
);
|
|
114
|
+
}
|
|
115
|
+
if (submission.txHashes.length === 0) {
|
|
116
|
+
throw new SwapSdkError(
|
|
117
|
+
"BROADCAST_FAILED",
|
|
118
|
+
"broadcast",
|
|
119
|
+
"NEAR wallet returned no transaction hashes"
|
|
120
|
+
);
|
|
121
|
+
}
|
|
122
|
+
return confirm(adapter, submission, context);
|
|
123
|
+
}
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
async function confirm(adapter, submission, context) {
|
|
127
|
+
const txHash = submission.txHashes[submission.txHashes.length - 1];
|
|
128
|
+
if (context.waitFor === "submitted" || !adapter.waitForTransactions) {
|
|
129
|
+
return {
|
|
130
|
+
status: "submitted",
|
|
131
|
+
txHash,
|
|
132
|
+
txHashes: submission.txHashes,
|
|
133
|
+
...submission.raw !== void 0 ? { raw: submission.raw } : {}
|
|
134
|
+
};
|
|
135
|
+
}
|
|
136
|
+
try {
|
|
137
|
+
const confirmation = await adapter.waitForTransactions(
|
|
138
|
+
submission.txHashes,
|
|
139
|
+
{ signal: context.signal }
|
|
140
|
+
);
|
|
141
|
+
return {
|
|
142
|
+
status: "source-confirmed",
|
|
143
|
+
txHash,
|
|
144
|
+
txHashes: submission.txHashes,
|
|
145
|
+
raw: confirmation ?? submission.raw
|
|
146
|
+
};
|
|
147
|
+
} catch (error) {
|
|
148
|
+
throw mapExecutorError(
|
|
149
|
+
error,
|
|
150
|
+
adapter,
|
|
151
|
+
"broadcast",
|
|
152
|
+
"BROADCAST_FAILED",
|
|
153
|
+
"Failed while confirming NEAR transactions"
|
|
154
|
+
);
|
|
155
|
+
}
|
|
156
|
+
}
|
|
157
|
+
|
|
158
|
+
export { createNearExecutor };
|
|
159
|
+
//# sourceMappingURL=near.mjs.map
|
|
160
|
+
//# sourceMappingURL=near.mjs.map
|