Skip to content
This repository was archived by the owner on Aug 6, 2025. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
28 changes: 16 additions & 12 deletions src/features/gift/actors/giftMakerPublishingActor.ts
Original file line number Diff line number Diff line change
@@ -1,8 +1,9 @@
import { solverRelay } from "@defuse-protocol/internal-utils"
import { assign, fromPromise, setup } from "xstate"
import { logger } from "../../../logger"
import {
type PublishIntentsErr,
publishIntents,
convertPublishIntentsToLegacyFormat,
} from "../../../sdk/solverRelay/publishIntents"
import type { MultiPayload } from "../../../types/defuse-contracts-types"
import { assert } from "../../../utils/assert"
Expand Down Expand Up @@ -41,17 +42,20 @@ export const giftMakerPublishingActor = setup({
},
actors: {
publishActor: fromPromise(({ input }: { input: MultiPayload }) => {
return publishIntents({
quote_hashes: [],
signed_datas: [input],
}).then((result) => {
if (result.isErr()) {
return { tag: "err" as const, value: result.unwrapErr() }
}
const intentHashes = result.unwrap()
assert(intentHashes != null)
return { tag: "ok" as const, value: intentHashes }
})
return solverRelay
.publishIntents({
quote_hashes: [],
signed_datas: [input],
})
.then(convertPublishIntentsToLegacyFormat)
.then((result) => {
if (result.isErr()) {
return { tag: "err" as const, value: result.unwrapErr() }
}
const intentHashes = result.unwrap()
assert(intentHashes != null)
return { tag: "ok" as const, value: intentHashes }
})
}),
},
actions: {
Expand Down
13 changes: 8 additions & 5 deletions src/features/gift/actors/shared/giftClaimActor.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,11 @@
import { solverRelay } from "@defuse-protocol/internal-utils"
import { type SignerCredentials, formatSignedIntent } from "src/core/formatters"
import type { MultiPayload } from "src/types/defuse-contracts-types"
import { assertEvent, assign, fromPromise, setup } from "xstate"
import { logger } from "../../../../logger"
import {
type PublishIntentsErr,
publishIntents,
convertPublishIntentsToLegacyFormat,
} from "../../../../sdk/solverRelay/publishIntents"
import { waitForIntentSettlement } from "../../../../sdk/solverRelay/waitForIntentSettlement"
import { assert } from "../../../../utils/assert"
Expand Down Expand Up @@ -114,10 +115,12 @@ export const giftClaimActor = setup({
}: {
input: { multiPayload: MultiPayload }
}): Promise<GiftPublishActorOutput> => {
const result = await publishIntents({
quote_hashes: [],
signed_datas: [input.multiPayload],
})
const result = await solverRelay
.publishIntents({
quote_hashes: [],
signed_datas: [input.multiPayload],
})
.then(convertPublishIntentsToLegacyFormat)
if (result.isErr()) {
return { tag: "err" as const, value: result.unwrapErr() }
}
Expand Down
8 changes: 5 additions & 3 deletions src/features/machines/swapIntentMachine.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import type { FeeEstimation } from "@defuse-protocol/bridge-sdk"
import { errors } from "@defuse-protocol/internal-utils"
import { errors, solverRelay } from "@defuse-protocol/internal-utils"
import { secp256k1 } from "@noble/curves/secp256k1"
import type { providers } from "near-api-js"
import { assign, fromPromise, setup } from "xstate"
import { settings } from "../../constants/settings"
import { logger } from "../../logger"
import { publishIntent } from "../../sdk/solverRelay/publishIntent"
import { convertPublishIntentToLegacyFormat } from "../../sdk/solverRelay/utils/parseFailedPublishError"
import { emitEvent } from "../../services/emitter"
import type { AggregatedQuote } from "../../services/quoteService"
import type { AuthMethod } from "../../types/authHandle"
Expand Down Expand Up @@ -264,7 +264,9 @@ export const swapIntentMachine = setup({
quoteHashes: string[]
}
}) =>
publishIntent(input.signatureData, input.userInfo, input.quoteHashes)
solverRelay
.publishIntent(input.signatureData, input.userInfo, input.quoteHashes)
.then(convertPublishIntentToLegacyFormat)
),
},
guards: {
Expand Down
30 changes: 17 additions & 13 deletions src/features/otcDesk/actors/otcMakerOrderCancellationActor.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,12 @@
import { solverRelay } from "@defuse-protocol/internal-utils"
import { base64 } from "@scure/base"
import { createEmptyIntentMessage } from "src/core/messages"
import { assertEvent, assign, fromPromise, setup } from "xstate"
import type { SignerCredentials } from "../../../core/formatters"
import { logger } from "../../../logger"
import {
type PublishIntentsErr,
publishIntents,
convertPublishIntentsToLegacyFormat,
} from "../../../sdk/solverRelay/publishIntents"
import type { MultiPayload } from "../../../types/defuse-contracts-types"
import type { WalletSignatureResult } from "../../../types/walletMessage"
Expand Down Expand Up @@ -65,18 +66,21 @@ export const otcMakerOrderCancellationActor = setup({
signActor: signIntentMachine,
publishActor: fromPromise(
({ input }: { input: { multiPayload: MultiPayload } }) => {
return publishIntents({
quote_hashes: [],
signed_datas: [input.multiPayload],
}).then((result) => {
if (result.isErr()) {
return { tag: "err" as const, value: result.unwrapErr() }
}
const intentHashes = result.unwrap()
const intentHash = intentHashes[0]
assert(intentHash != null)
return { tag: "ok" as const, value: intentHash }
})
return solverRelay
.publishIntents({
quote_hashes: [],
signed_datas: [input.multiPayload],
})
.then(convertPublishIntentsToLegacyFormat)
.then((result) => {
if (result.isErr()) {
return { tag: "err" as const, value: result.unwrapErr() }
}
const intentHashes = result.unwrap()
const intentHash = intentHashes[0]
assert(intentHash != null)
return { tag: "ok" as const, value: intentHash }
})
}
),
},
Expand Down
13 changes: 8 additions & 5 deletions src/features/otcDesk/hooks/useOtcTakerConfirmTrade.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { solverRelay } from "@defuse-protocol/internal-utils"
import { useMutation } from "@tanstack/react-query"
import { Err, type Result } from "@thames/monads"
import { useContext } from "react"
Expand All @@ -8,7 +9,7 @@ import {
import { createSwapIntentMessage } from "../../../core/messages"
import {
type PublishIntentsErr,
publishIntents,
convertPublishIntentsToLegacyFormat,
} from "../../../sdk/solverRelay/publishIntents"
import { emitEvent } from "../../../services/emitter"
import type { MultiPayload } from "../../../types/defuse-contracts-types"
Expand Down Expand Up @@ -95,10 +96,12 @@ export function useOtcTakerConfirmTrade({
signerCredentials
)

const result = await publishIntents({
quote_hashes: quoteHashesResult.unwrap(),
signed_datas: [multiPayload, makerMultiPayload],
})
const result = await solverRelay
.publishIntents({
quote_hashes: quoteHashesResult.unwrap(),
signed_datas: [multiPayload, makerMultiPayload],
})
.then(convertPublishIntentsToLegacyFormat)

return result.map((intentHashes) => {
return {
Expand Down
9 changes: 6 additions & 3 deletions src/features/tokenMigration/machines/tokenMigrationMachine.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import { solverRelay } from "@defuse-protocol/internal-utils"
import { assign, fromPromise, setup } from "xstate"
import { config } from "../../../config"
import { nearClient } from "../../../constants/nearClient"
import type { SignerCredentials } from "../../../core/formatters"
import { logger } from "../../../logger"
import { publishIntent } from "../../../sdk/solverRelay/publishIntent"
import { convertPublishIntentToLegacyFormat } from "../../../sdk/solverRelay/utils/parseFailedPublishError"
import {
type IntentSettlementResult,
waitForIntentSettlement,
Expand Down Expand Up @@ -56,8 +57,10 @@ export const tokenMigrationMachine = setup({
signIntent: signIntentMachine,

publishIntent: fromPromise(
({ input }: { input: Parameters<typeof publishIntent> }) =>
publishIntent(...input)
({ input }: { input: Parameters<typeof solverRelay.publishIntent> }) =>
solverRelay
.publishIntent(...input)
.then(convertPublishIntentToLegacyFormat)
),

waitForIntentSettlement: fromPromise(
Expand Down
50 changes: 0 additions & 50 deletions src/sdk/solverRelay/publishIntent.ts

This file was deleted.

92 changes: 42 additions & 50 deletions src/sdk/solverRelay/publishIntents.ts
Original file line number Diff line number Diff line change
@@ -1,62 +1,54 @@
import { retry } from "@lifeomic/attempt"
import type { solverRelay } from "@defuse-protocol/internal-utils"
import { Err, Ok, type Result } from "@thames/monads"
import { logger } from "../../logger"
import * as solverRelayClient from "./solverRelayHttpClient"
import {
type ParsedPublishErrors,
parseFailedPublishError,
} from "./utils/parseFailedPublishError"

export async function publishIntents(
...args: Parameters<typeof solverRelayClient.publishIntents>
): Promise<Result<PublishIntentsOk, PublishIntentsErr>> {
const [params, requestConfig] = args
return retry(
() =>
solverRelayClient.publishIntents(params, {
timeout: 30000,
...requestConfig,
}),
{
delay: 1000,
factor: 1.5,
maxAttempts: 7,
jitter: true,
minDelay: 1000,
}
)
.then(parsePublishIntentsResponse, (err) => {
logger.error(new Error("Failed to publish intents", { cause: err }))
return Err<PublishIntentsOk, PublishIntentsErr>({
reason: "RELAY_PUBLISH_NETWORK_ERROR",
})
})
.then((result) => {
if (result.isErr()) {
const err = result.unwrapErr()
if (err.reason === "RELAY_PUBLISH_UNKNOWN_ERROR") {
logger.error(err.serverReason)
}
}
return result
})
}
import type { ParsedPublishErrors } from "./utils/parseFailedPublishError"

export type PublishIntentsOk = string[]
export type PublishIntentsErr =
| ParsedPublishErrors
| { reason: "RELAY_PUBLISH_NETWORK_ERROR" }

function parsePublishIntentsResponse(
response: Awaited<ReturnType<typeof solverRelayClient.publishIntents>>
): Result<PublishIntentsOk, PublishIntentsErr> {
if (response.status === "OK") {
return Ok(response.intent_hashes)
export function convertPublishIntentsToLegacyFormat(
result: Result<
solverRelay.PublishIntentsReturnType,
solverRelay.PublishIntentsErrorType
>
): Promise<Result<PublishIntentsOk, PublishIntentsErr>> {
if (result.isOk()) {
return Promise.resolve(Ok(result.unwrap()))
}

if (response.reason === "already processed") {
return Ok(response.intent_hashes)
const error = result.unwrapErr()
const errorCode = error.code

// Map new PublishErrorCode to old ParsedPublishErrors format
let reason: ParsedPublishErrors["reason"]
switch (errorCode) {
case "SIGNATURE_EXPIRED":
reason = "RELAY_PUBLISH_SIGNATURE_EXPIRED"
break
case "INTERNAL_ERROR":
reason = "RELAY_PUBLISH_INTERNAL_ERROR"
break
case "SIGNATURE_INVALID":
reason = "RELAY_PUBLISH_SIGNATURE_INVALID"
break
case "NONCE_USED":
reason = "RELAY_PUBLISH_NONCE_USED"
break
case "INSUFFICIENT_BALANCE":
reason = "RELAY_PUBLISH_INSUFFICIENT_BALANCE"
break
case "PUBLIC_KEY_NOT_EXIST":
reason = "RELAY_PUBLISH_PUBLIC_NOT_EXIST"
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue

Fix typo in error reason

The reason should be RELAY_PUBLISH_PUBLIC_KEY_NOT_EXIST to match the pattern and be more descriptive.

-      reason = "RELAY_PUBLISH_PUBLIC_NOT_EXIST"
+      reason = "RELAY_PUBLISH_PUBLIC_KEY_NOT_EXIST"
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
reason = "RELAY_PUBLISH_PUBLIC_NOT_EXIST"
reason = "RELAY_PUBLISH_PUBLIC_KEY_NOT_EXIST"
🤖 Prompt for AI Agents
In src/sdk/solverRelay/publishIntents.ts at line 42, the error reason string is
incorrectly set to "RELAY_PUBLISH_PUBLIC_NOT_EXIST". Update this string to
"RELAY_PUBLISH_PUBLIC_KEY_NOT_EXIST" to correct the typo and maintain
consistency with the naming pattern.

break
default:
reason = "RELAY_PUBLISH_UNKNOWN_ERROR"
}

return Err(parseFailedPublishError(response))
return Promise.resolve(
Err({
reason,
serverReason: errorCode,
})
)
}
26 changes: 0 additions & 26 deletions src/sdk/solverRelay/solverRelayHttpClient/apis.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,32 +14,6 @@ export async function quote(
return result as any
}

export async function publishIntent(
params: types.PublishIntentRequest["params"][0],
config: types.RequestConfig = {}
): Promise<types.PublishIntentResponse["result"]> {
const result = await jsonRPCRequest<types.PublishIntentRequest>(
"publish_intent",
params,
config
)
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
return result as any
}

export async function publishIntents(
params: types.PublishIntentsRequest["params"][0],
config: types.RequestConfig = {}
): Promise<types.PublishIntentsResponse["result"]> {
const result = await jsonRPCRequest<types.PublishIntentsRequest>(
"publish_intents",
params,
config
)
// biome-ignore lint/suspicious/noExplicitAny: <explanation>
return result as any
}

export async function getStatus(
params: types.GetStatusRequest["params"][0],
config: types.RequestConfig = {}
Expand Down
Loading
Loading