@funkit/fun-relay 0.1.1 → 0.1.3

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/CHANGELOG.md CHANGED
@@ -1,5 +1,18 @@
1
1
  # @funkit/fun-relay
2
2
 
3
+ ## 0.1.3
4
+
5
+ ### Patch Changes
6
+
7
+ - 4c74602: chore: support katana chain
8
+ - 2a9539a: feat: fallback price fetch to relay implementation
9
+
10
+ ## 0.1.2
11
+
12
+ ### Patch Changes
13
+
14
+ - 6cb808b: feat(relay): add exact input quote handling
15
+
3
16
  ## 0.1.1
4
17
 
5
18
  ### Patch Changes
package/dist/index.d.ts CHANGED
@@ -1,6 +1,9 @@
1
1
  export { getRelayClient, initializeRelayClient, type InitializeRelayClientParams, } from './src/client';
2
+ export { FUN_RELAY_REFERRER, FUN_RELAY_REVENUE_WALLET, RELAY_TERMINAL_STATUSES, } from './src/constants';
2
3
  export { type ExecuteRelayQuoteParams, executeRelayQuote, getRelayExecutionInfo, } from './src/execution';
3
- export { type GetRelayQuoteParams, getRelayQuote } from './src/quote';
4
- export { getRelayExecutionRefundState, getRelayExecutionState, isRelayExecutionTerminalStatus, } from './src/utils';
5
- export { LogLevel, type RelayExecutionInfo, type RelayExecutionStatus, } from './src/types';
4
+ export { computeFunRelayFeeBps, parseRelayFees, } from './src/fees';
5
+ export { getRelayAssetPriceInfo } from './src/price';
6
+ export { type GetRelayQuoteParams, getRelayQuote, type RelayQuote, } from './src/quote';
7
+ export { getRelayExecutionRefundState, getRelayExecutionState, isRelayExecutionTerminalStatus, convertFunToRelayTokenAddress, } from './src/utils';
8
+ export { LogLevel, type RelayExecutionInfo, type RelayExecutionStatus, type RelayTokenPriceInfo, } from './src/types';
6
9
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,KAAK,2BAA2B,GACjC,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,KAAK,uBAAuB,EAC5B,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EAAE,KAAK,mBAAmB,EAAE,aAAa,EAAE,MAAM,aAAa,CAAA;AACrE,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,8BAA8B,GAC/B,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,QAAQ,EACR,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,GAC1B,MAAM,aAAa,CAAA"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,qBAAqB,EACrB,KAAK,2BAA2B,GACjC,MAAM,cAAc,CAAA;AACrB,OAAO,EACL,kBAAkB,EAClB,wBAAwB,EACxB,uBAAuB,GACxB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,KAAK,uBAAuB,EAC5B,iBAAiB,EACjB,qBAAqB,GACtB,MAAM,iBAAiB,CAAA;AACxB,OAAO,EACL,qBAAqB,EACrB,cAAc,GACf,MAAM,YAAY,CAAA;AACnB,OAAO,EAAE,sBAAsB,EAAE,MAAM,aAAa,CAAA;AACpD,OAAO,EACL,KAAK,mBAAmB,EACxB,aAAa,EACb,KAAK,UAAU,GAChB,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,4BAA4B,EAC5B,sBAAsB,EACtB,8BAA8B,EAC9B,6BAA6B,GAC9B,MAAM,aAAa,CAAA;AACpB,OAAO,EACL,QAAQ,EACR,KAAK,kBAAkB,EACvB,KAAK,oBAAoB,EACzB,KAAK,mBAAmB,GACzB,MAAM,aAAa,CAAA"}
package/dist/index.js CHANGED
@@ -20,15 +20,22 @@ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: tru
20
20
  // index.ts
21
21
  var index_exports = {};
22
22
  __export(index_exports, {
23
- LogLevel: () => import_relay_sdk3.LogLevel,
23
+ FUN_RELAY_REFERRER: () => FUN_RELAY_REFERRER,
24
+ FUN_RELAY_REVENUE_WALLET: () => FUN_RELAY_REVENUE_WALLET,
25
+ LogLevel: () => import_relay_sdk2.LogLevel,
26
+ RELAY_TERMINAL_STATUSES: () => RELAY_TERMINAL_STATUSES,
27
+ computeFunRelayFeeBps: () => computeFunRelayFeeBps,
28
+ convertFunToRelayTokenAddress: () => convertFunToRelayTokenAddress,
24
29
  executeRelayQuote: () => executeRelayQuote,
30
+ getRelayAssetPriceInfo: () => getRelayAssetPriceInfo,
25
31
  getRelayClient: () => getRelayClient,
26
32
  getRelayExecutionInfo: () => getRelayExecutionInfo,
27
33
  getRelayExecutionRefundState: () => getRelayExecutionRefundState,
28
34
  getRelayExecutionState: () => getRelayExecutionState,
29
35
  getRelayQuote: () => getRelayQuote,
30
36
  initializeRelayClient: () => initializeRelayClient,
31
- isRelayExecutionTerminalStatus: () => isRelayExecutionTerminalStatus
37
+ isRelayExecutionTerminalStatus: () => isRelayExecutionTerminalStatus,
38
+ parseRelayFees: () => parseRelayFees
32
39
  });
33
40
  module.exports = __toCommonJS(index_exports);
34
41
 
@@ -44,7 +51,7 @@ function initializeRelayClient({
44
51
  baseApiUrl: import_relay_sdk.MAINNET_RELAY_API,
45
52
  chains: chains.map(import_relay_sdk.convertViemChainToRelayChain),
46
53
  logger: (message) => {
47
- logger.log("[RelayClient]:", message);
54
+ logger.info("[RelayClient]:", message);
48
55
  }
49
56
  });
50
57
  }
@@ -56,14 +63,29 @@ function getRelayClient() {
56
63
  return client;
57
64
  }
58
65
 
59
- // src/execution.ts
66
+ // src/types.ts
60
67
  var import_relay_sdk2 = require("@reservoir0x/relay-sdk");
68
+
69
+ // src/constants.ts
70
+ var FUNKIT_NATIVE_TOKEN = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
71
+ var RELAY_NATIVE_TOKEN = "0x0000000000000000000000000000000000000000";
72
+ var FUN_RELAY_REVENUE_WALLET = "0xb61562d83aEC43a050A06BED12Ac2bD8f9BFfd5E";
73
+ var FUN_RELAY_REFERRER = "funxyz";
74
+ var RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 3e3;
75
+ var RELAY_TERMINAL_STATUSES = [
76
+ "refund" /* REFUND */,
77
+ "failure" /* FAILURE */,
78
+ "success" /* SUCCESS */
79
+ ];
80
+
81
+ // src/execution.ts
82
+ var import_relay_sdk3 = require("@reservoir0x/relay-sdk");
61
83
  async function executeRelayQuote({
62
84
  logger,
63
85
  onConfirmed,
64
86
  onError,
87
+ onProgress,
65
88
  relayQuote,
66
- stepMessageSetter,
67
89
  walletClient
68
90
  }) {
69
91
  await getRelayClient().actions.execute({
@@ -80,7 +102,7 @@ async function executeRelayQuote({
80
102
  error
81
103
  }) => {
82
104
  const logPrefix = "onRelayProgress";
83
- logger.log(`${logPrefix}:params`, {
105
+ logger.info(`${logPrefix}:params`, {
84
106
  steps,
85
107
  currentStep,
86
108
  fees,
@@ -90,9 +112,9 @@ async function executeRelayQuote({
90
112
  details,
91
113
  error
92
114
  });
93
- stepMessageSetter(currentStep?.action ?? "");
115
+ onProgress?.(currentStep ?? null);
94
116
  if (error) {
95
- logger.log(`${logPrefix}:errorDetected`, error);
117
+ logger.info(`${logPrefix}:errorDetected`, error);
96
118
  await onError(error).catch((e) => {
97
119
  logger.error(`${logPrefix}:onErrorFailed`, e);
98
120
  });
@@ -101,7 +123,7 @@ async function executeRelayQuote({
101
123
  // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1748381169792379
102
124
  txHashes && txHashes.length > 0 && txHashes.length === steps.length
103
125
  ) {
104
- logger.log(`${logPrefix}:completed`, txHashes);
126
+ logger.info(`${logPrefix}:completed`, txHashes);
105
127
  await onConfirmed(txHashes[0].txHash).catch((e) => {
106
128
  logger.error(`${logPrefix}:onConfirmedFailed`, e);
107
129
  });
@@ -110,7 +132,7 @@ async function executeRelayQuote({
110
132
  });
111
133
  }
112
134
  async function getRelayExecutionInfo(requestId) {
113
- const url = `${import_relay_sdk2.MAINNET_RELAY_API}/intents/status/v2?requestId=${requestId}`;
135
+ const url = `${import_relay_sdk3.MAINNET_RELAY_API}/intents/status/v2?requestId=${requestId}`;
114
136
  const response = await fetch(url);
115
137
  if (!response.ok) {
116
138
  throw Error(response.statusText);
@@ -119,21 +141,6 @@ async function getRelayExecutionInfo(requestId) {
119
141
  return data;
120
142
  }
121
143
 
122
- // src/quote.ts
123
- var import_viem = require("viem");
124
-
125
- // src/constants.ts
126
- var FUNKIT_NATIVE_TOKEN = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
127
- var RELAY_NATIVE_TOKEN = "0x0000000000000000000000000000000000000000";
128
- var FUN_RELAY_REVENUE_WALLET = "0xb61562d83aEC43a050A06BED12Ac2bD8f9BFfd5E";
129
- var FUN_RELAY_REFERRER = "funxyz";
130
- var RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 3e3;
131
- var RELAY_TERMINAL_STATUSES = [
132
- "refund",
133
- "failure",
134
- "success"
135
- ];
136
-
137
144
  // src/fees.ts
138
145
  function computeFunRelayFeeBps({
139
146
  isSameToken
@@ -156,7 +163,7 @@ function parseRelayFees({
156
163
  const totalLpFeesUsd = funLpFeesUsd + relayLpFeesUsd;
157
164
  const totalLpFeesFromAmount = funLpFeesFromAmount + relayLpFeesFromAmount;
158
165
  const totalLpFeesFromAmountBaseUnit = funLpFeesFromAmountBaseUnit + relayLpFeesFromAmountBaseUnit;
159
- logger.log("parseRelayFees", {
166
+ logger.info("parseRelayFees", {
160
167
  relayGasFeesUsd,
161
168
  funLpFeesUsd,
162
169
  funLpFeesFromAmount,
@@ -177,8 +184,23 @@ function parseRelayFees({
177
184
  };
178
185
  }
179
186
 
180
- // src/types.ts
181
- var import_relay_sdk3 = require("@reservoir0x/relay-sdk");
187
+ // src/price.ts
188
+ var import_relay_sdk4 = require("@reservoir0x/relay-sdk");
189
+ async function getRelayAssetPriceInfo({
190
+ chainId,
191
+ address
192
+ }) {
193
+ const url = `${import_relay_sdk4.MAINNET_RELAY_API}/currencies/token/price?chainId=${chainId}&address=${address}`;
194
+ const response = await fetch(url);
195
+ if (!response.ok) {
196
+ throw Error(response.statusText);
197
+ }
198
+ const data = await response.json();
199
+ return data;
200
+ }
201
+
202
+ // src/quote.ts
203
+ var import_viem = require("viem");
182
204
 
183
205
  // src/utils.ts
184
206
  function convertFunToRelayTokenAddress(address) {
@@ -212,22 +234,22 @@ function isRelayExecutionTerminalStatus(info) {
212
234
 
213
235
  // src/quote.ts
214
236
  async function getRelayQuote({
215
- actionParams,
216
237
  logger,
217
- toChainId,
218
- toTokenAddress,
219
- toTokenAmount,
220
- toTokenDecimals,
221
- fromChainId,
222
- fromTokenAddress,
223
- recipientAddress,
224
- userAddress
238
+ ...params
225
239
  }) {
240
+ const {
241
+ actionParams,
242
+ fromChainId,
243
+ fromTokenAddress,
244
+ options,
245
+ recipientAddress,
246
+ toChainId,
247
+ toTokenAddress,
248
+ userAddress
249
+ } = params;
226
250
  try {
227
251
  const relayClient = getRelayClient();
228
- const toMultipler = 10 ** toTokenDecimals;
229
- const toAmountBaseUnitBI = BigInt(Math.floor(toTokenAmount * toMultipler));
230
- const toAmountBaseUnitBIString = toAmountBaseUnitBI.toString();
252
+ const tokenAmountBaseUnit = params.tradeType === "EXACT_INPUT" ? params.fromTokenAmountBaseUnit : params.toTokenAmountBaseUnit;
231
253
  const txs = actionParams?.map((action) => {
232
254
  const data = (0, import_viem.encodeFunctionData)({
233
255
  abi: action.contractAbi,
@@ -240,18 +262,9 @@ async function getRelayQuote({
240
262
  value: String(action.value ?? 0n)
241
263
  };
242
264
  });
243
- logger.log("getRelayQuoteParams", {
244
- actionParams,
245
- toChainId,
246
- toTokenAddress,
247
- toTokenAmount,
248
- toTokenDecimals,
249
- fromChainId,
250
- fromTokenAddress,
251
- recipientAddress,
252
- userAddress,
253
- relayClient,
254
- toAmountBaseUnitBI: toAmountBaseUnitBIString,
265
+ logger.info("getRelayQuoteParams", {
266
+ ...params,
267
+ tokenAmountBaseUnit,
255
268
  txs
256
269
  });
257
270
  const relayQuote = await relayClient.actions.getQuote({
@@ -259,9 +272,9 @@ async function getRelayQuote({
259
272
  toChainId: Number(toChainId),
260
273
  currency: convertFunToRelayTokenAddress(fromTokenAddress),
261
274
  toCurrency: convertFunToRelayTokenAddress(toTokenAddress),
262
- amount: toAmountBaseUnitBIString,
275
+ amount: tokenAmountBaseUnit.toString(),
263
276
  recipient: recipientAddress,
264
- tradeType: "EXACT_OUTPUT",
277
+ tradeType: params.tradeType,
265
278
  user: userAddress,
266
279
  ...txs && { txs },
267
280
  options: {
@@ -273,10 +286,11 @@ async function getRelayQuote({
273
286
  }).toString(),
274
287
  recipient: FUN_RELAY_REVENUE_WALLET
275
288
  }
276
- ]
289
+ ],
290
+ ...options
277
291
  }
278
292
  });
279
- logger.log("relayQuote", relayQuote);
293
+ logger.info("relayQuote", relayQuote);
280
294
  const estSubtotalUsd = Number(
281
295
  relayQuote.details?.currencyOut?.amountUsd || 0
282
296
  );
@@ -287,6 +301,9 @@ async function getRelayQuote({
287
301
  if (!relayRequestId) {
288
302
  throw new Error("Relay quote does not contain a requestId");
289
303
  }
304
+ if (!relayQuote.details?.currencyIn || !relayQuote.details?.currencyOut) {
305
+ throw new Error("Relay quote does not contain trade details");
306
+ }
290
307
  const {
291
308
  relayGasFeesUsd,
292
309
  totalLpFeesUsd,
@@ -298,29 +315,32 @@ async function getRelayQuote({
298
315
  const estSubtotalFromAmountBaseUnit = (BigInt(fromAmountBaseUnitString) - totalFeesFromAmountBaseUnit).toString();
299
316
  return {
300
317
  quoteId: relayRequestId,
301
- estTotalFromAmount: fromAmountString,
302
- estSubtotalFromAmount,
303
- estTotalFromAmountBaseUnit: fromAmountBaseUnitString,
304
- estSubtotalFromAmountBaseUnit,
318
+ estCheckoutTimeMs: (relayQuote.details.timeEstimate || 0) * 1e3 + RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,
305
319
  estFeesFromAmount: totalFeesFromAmount.toString(),
306
320
  estFeesFromAmountBaseUnit: totalFeesFromAmountBaseUnit.toString(),
307
- fromTokenAddress,
308
321
  estFeesUsd: totalFeesUsd,
322
+ estMarketMakerGasUsd: relayGasFeesUsd,
323
+ estSubtotalFromAmount,
324
+ estSubtotalFromAmountBaseUnit,
309
325
  estSubtotalUsd,
326
+ estTotalFromAmount: fromAmountString,
327
+ estTotalFromAmountBaseUnit: fromAmountBaseUnitString,
310
328
  estTotalUsd,
311
- estCheckoutTimeMs: (relayQuote.details?.timeEstimate || 0) * 1e3 + RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,
312
- estMarketMakerGasUsd: relayGasFeesUsd,
329
+ finalToAmountBaseUnit: relayQuote.details.currencyOut.amount ?? "0",
330
+ // TODO: Or do we want 'minimumAmount'?
331
+ fromTokenAddress,
313
332
  lpFeePercentage: 0,
314
333
  // TODO: ?
315
334
  lpFeeUsd: totalLpFeesUsd,
316
335
  metadata: {
336
+ fromAmountBaseUnit: params.tradeType === "EXACT_INPUT" ? tokenAmountBaseUnit.toString() : relayQuote.details.currencyIn.amount ?? "0",
317
337
  relayQuote,
318
- toAmountBaseUnit: toAmountBaseUnitBIString
338
+ toAmountBaseUnit: params.tradeType === "EXACT_INPUT" ? relayQuote.details.currencyOut.amount ?? "0" : tokenAmountBaseUnit.toString()
319
339
  }
320
340
  };
321
341
  } catch (err) {
322
342
  throw new Error(
323
- `An error occured trying to generate a relay quote: ${err instanceof Error ? err.message : JSON.stringify(err)}`
343
+ `An error occurred trying to generate a relay quote: ${err instanceof Error ? err.message : JSON.stringify(err)}`
324
344
  );
325
345
  }
326
346
  }
package/dist/index.js.map CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../index.ts", "../src/client.ts", "../src/execution.ts", "../src/quote.ts", "../src/constants.ts", "../src/fees.ts", "../src/types.ts", "../src/utils.ts"],
4
- "sourcesContent": ["export {\n getRelayClient,\n initializeRelayClient,\n type InitializeRelayClientParams,\n} from './src/client'\nexport {\n type ExecuteRelayQuoteParams,\n executeRelayQuote,\n getRelayExecutionInfo,\n} from './src/execution'\nexport { type GetRelayQuoteParams, getRelayQuote } from './src/quote'\nexport {\n getRelayExecutionRefundState,\n getRelayExecutionState,\n isRelayExecutionTerminalStatus,\n} from './src/utils'\nexport {\n LogLevel,\n type RelayExecutionInfo,\n type RelayExecutionStatus,\n} from './src/types'\n", "import {\n MAINNET_RELAY_API,\n type RelayClient,\n type RelayClientOptions,\n convertViemChainToRelayChain,\n createClient,\n getClient,\n} from '@reservoir0x/relay-sdk'\nimport type { Chain } from 'viem'\nimport type { Logger } from './types'\n\nexport type InitializeRelayClientParams = Omit<\n RelayClientOptions,\n 'baseApiUrl' | 'chains' | 'logger'\n> & {\n chains: Chain[]\n logger: Logger\n}\n\n/**\n * Initializes a global instance of the RelayClient\n * https://docs.relay.link/references/sdk/createClient\n */\nexport function initializeRelayClient({\n chains,\n logger,\n ...options\n}: InitializeRelayClientParams): RelayClient {\n return createClient({\n ...options,\n baseApiUrl: MAINNET_RELAY_API,\n chains: chains.map(convertViemChainToRelayChain),\n logger: (message) => {\n logger.log('[RelayClient]:', message)\n },\n })\n}\n\n/**\n * Gets the global instance of the RelayClient\n */\nexport function getRelayClient(): RelayClient {\n const client = getClient()\n\n if (!client) {\n throw new Error('Relay client is not defined')\n }\n\n return client\n}\n", "import { type Execute, MAINNET_RELAY_API } from '@reservoir0x/relay-sdk'\nimport type { Hex, WalletClient } from 'viem'\nimport { getRelayClient } from './client'\nimport type { Logger, RelayExecutionInfo } from './types'\n\nexport interface ExecuteRelayQuoteParams {\n logger: Logger\n onConfirmed: (txHash: Hex) => Promise<void>\n onError: (error: Error) => Promise<void>\n relayQuote: Execute\n stepMessageSetter: (message: string) => void\n walletClient: WalletClient\n}\n\n// TODO: Add unit tests for this once impl is settled\nexport async function executeRelayQuote({\n logger,\n onConfirmed,\n onError,\n relayQuote,\n stepMessageSetter,\n walletClient,\n}: ExecuteRelayQuoteParams) {\n await getRelayClient().actions.execute({\n quote: relayQuote,\n wallet: walletClient,\n onProgress: async ({\n steps,\n fees,\n breakdown,\n currentStep,\n currentStepItem,\n txHashes,\n details,\n error,\n }) => {\n const logPrefix = 'onRelayProgress'\n logger.log(`${logPrefix}:params`, {\n steps,\n currentStep,\n fees,\n breakdown,\n currentStepItem,\n txHashes,\n details,\n error,\n })\n\n stepMessageSetter(currentStep?.action ?? '')\n\n if (error) {\n logger.log(`${logPrefix}:errorDetected`, error)\n await onError(error).catch((e) => {\n logger.error(`${logPrefix}:onErrorFailed`, e)\n })\n } else if (\n // We can redirect as soon as all the required user steps are done\n // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1748381169792379\n txHashes &&\n txHashes.length > 0 &&\n txHashes.length === steps.length\n ) {\n logger.log(`${logPrefix}:completed`, txHashes)\n // Can we assume its completed here?\n // Use first txHash as the main txHash in fun DE table\n await onConfirmed(txHashes[0].txHash as Hex).catch((e) => {\n logger.error(`${logPrefix}:onConfirmedFailed`, e)\n })\n }\n },\n })\n}\n\nexport async function getRelayExecutionInfo(\n requestId: string,\n): Promise<RelayExecutionInfo> {\n const url = `${MAINNET_RELAY_API}/intents/status/v2?requestId=${requestId}`\n const response = await fetch(url)\n if (!response.ok) {\n throw Error(response.statusText)\n }\n\n const data = await response.json()\n return data as RelayExecutionInfo\n}\n", "import { type Address, encodeFunctionData } from 'viem'\nimport { getRelayClient } from './client'\nimport {\n FUN_RELAY_REFERRER,\n FUN_RELAY_REVENUE_WALLET,\n RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,\n} from './constants'\nimport { computeFunRelayFeeBps, parseRelayFees } from './fees'\nimport type {\n ApiFunkitCheckoutActionParams,\n CheckoutQuoteResponse,\n Logger,\n} from './types'\nimport { convertFunToRelayTokenAddress } from './utils'\n\nexport interface GetRelayQuoteParams {\n actionParams?: ApiFunkitCheckoutActionParams[]\n fromChainId: string\n fromTokenAddress: Address\n logger: Logger\n recipientAddress: Address | undefined\n toChainId: string\n toTokenAddress: Address\n toTokenAmount: number\n toTokenDecimals: number\n userAddress: Address | undefined\n}\n\nexport async function getRelayQuote({\n actionParams,\n logger,\n toChainId,\n toTokenAddress,\n toTokenAmount,\n toTokenDecimals,\n fromChainId,\n fromTokenAddress,\n recipientAddress,\n userAddress,\n}: GetRelayQuoteParams): Promise<CheckoutQuoteResponse> {\n try {\n const relayClient = getRelayClient()\n\n // Mirror logic in api-base (this is wrong)\n const toMultipler = 10 ** toTokenDecimals\n const toAmountBaseUnitBI = BigInt(Math.floor(toTokenAmount * toMultipler))\n const toAmountBaseUnitBIString = toAmountBaseUnitBI.toString()\n\n const txs = actionParams?.map((action) => {\n const data = encodeFunctionData({\n abi: action.contractAbi,\n args: action.functionArgs,\n functionName: action.functionName,\n })\n\n return {\n data,\n to: action.contractAddress,\n value: String(action.value ?? 0n),\n }\n })\n\n logger.log('getRelayQuoteParams', {\n actionParams,\n toChainId,\n toTokenAddress,\n toTokenAmount,\n toTokenDecimals,\n fromChainId,\n fromTokenAddress,\n recipientAddress,\n userAddress,\n relayClient,\n toAmountBaseUnitBI: toAmountBaseUnitBIString,\n txs,\n })\n\n // Get the relay quote\n const relayQuote = await relayClient.actions.getQuote({\n chainId: Number(fromChainId),\n toChainId: Number(toChainId),\n currency: convertFunToRelayTokenAddress(fromTokenAddress),\n toCurrency: convertFunToRelayTokenAddress(toTokenAddress),\n amount: toAmountBaseUnitBIString,\n recipient: recipientAddress,\n tradeType: 'EXACT_OUTPUT',\n user: userAddress,\n ...(txs && { txs }),\n options: {\n referrer: FUN_RELAY_REFERRER,\n appFees: [\n {\n fee: computeFunRelayFeeBps({\n isSameToken:\n fromChainId === toChainId &&\n fromTokenAddress.toLowerCase() === toTokenAddress.toLowerCase(),\n }).toString(),\n recipient: FUN_RELAY_REVENUE_WALLET,\n },\n ],\n },\n })\n\n // TODO: Handling for no route response\n\n logger.log('relayQuote', relayQuote)\n\n const estSubtotalUsd = Number(\n relayQuote.details?.currencyOut?.amountUsd || 0,\n )\n const estTotalUsd = Number(relayQuote.details?.currencyIn?.amountUsd || 0)\n // Get how much fromAmount is needed for the quote\n const fromAmountString =\n relayQuote.details?.currencyIn?.amountFormatted || '0'\n const fromAmountBaseUnitString =\n relayQuote.details?.currencyIn?.amount || '0'\n\n // RequestID will be consistent across steps in the quote\n // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1747774944603209\n const relayRequestId = relayQuote.steps[0]?.requestId\n\n // TODO: Verify with relay team if this is possible?\n if (!relayRequestId) {\n throw new Error('Relay quote does not contain a requestId')\n }\n\n const {\n relayGasFeesUsd,\n totalLpFeesUsd,\n totalFeesUsd,\n totalFeesFromAmount,\n totalFeesFromAmountBaseUnit,\n } = parseRelayFees({ fees: relayQuote.fees, logger })\n\n const estSubtotalFromAmount = (\n Number.parseFloat(fromAmountString) - totalFeesFromAmount\n ).toString()\n\n const estSubtotalFromAmountBaseUnit = (\n BigInt(fromAmountBaseUnitString) - totalFeesFromAmountBaseUnit\n ).toString()\n\n return {\n quoteId: relayRequestId,\n estTotalFromAmount: fromAmountString,\n estSubtotalFromAmount,\n estTotalFromAmountBaseUnit: fromAmountBaseUnitString,\n estSubtotalFromAmountBaseUnit: estSubtotalFromAmountBaseUnit,\n estFeesFromAmount: totalFeesFromAmount.toString(),\n estFeesFromAmountBaseUnit: totalFeesFromAmountBaseUnit.toString(),\n fromTokenAddress,\n estFeesUsd: totalFeesUsd,\n estSubtotalUsd,\n estTotalUsd,\n estCheckoutTimeMs:\n (relayQuote.details?.timeEstimate || 0) * 1000 +\n RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,\n estMarketMakerGasUsd: relayGasFeesUsd,\n lpFeePercentage: 0, // TODO: ?\n lpFeeUsd: totalLpFeesUsd,\n metadata: {\n relayQuote,\n toAmountBaseUnit: toAmountBaseUnitBIString,\n },\n }\n } catch (err) {\n throw new Error(\n `An error occured trying to generate a relay quote: ${\n err instanceof Error ? err.message : JSON.stringify(err)\n }`,\n )\n }\n}\n", "import type { Address } from 'viem'\nimport type { RelayExecutionStatus } from './types'\n\n/**\n * Fake address for a chain's native currency used by Funkit\n */\nexport const FUNKIT_NATIVE_TOKEN =\n '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' satisfies Address\n\n/**\n * Fake address for a chain's native currency used by Relay\n */\nexport const RELAY_NATIVE_TOKEN =\n '0x0000000000000000000000000000000000000000' satisfies Address\n\n/**\n * Wallet that receives the app fees collected by Relay\n */\nexport const FUN_RELAY_REVENUE_WALLET =\n '0xb61562d83aEC43a050A06BED12Ac2bD8f9BFfd5E' satisfies Address\n\n/**\n * Referred field in Relay quote\n */\nexport const FUN_RELAY_REFERRER = 'funxyz'\n\n/**\n * Buffer added to Relay's time estimate (which sometimes is 0)\n */\nexport const RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 3_000 // 3 seconds\n\nexport const RELAY_TERMINAL_STATUSES: RelayExecutionStatus[] = [\n 'refund',\n 'failure',\n 'success',\n]\n", "import type { CallFees } from '@reservoir0x/relay-sdk'\nimport type { Logger } from './types'\n\nexport function computeFunRelayFeeBps({\n isSameToken,\n}: {\n isSameToken: boolean\n}): number {\n // For now, we have a flat 2bps app fee for all relay transactions\n // TODO: Dynamic fee based on the transaction size, from token, to token, etc\n return isSameToken ? 0 : 2\n}\n\nexport function parseRelayFees({\n fees,\n logger,\n}: {\n fees: CallFees | undefined\n logger: Logger\n}) {\n // Gas fees, denominated in source chain native token\n const relayGasFeesUsd = Number.parseFloat(fees?.gas?.amountUsd || '0')\n\n // App fees, denominated in source chain token\n const funLpFeesUsd = Number.parseFloat(fees?.app?.amountUsd || '0')\n const funLpFeesFromAmount = Number.parseFloat(\n fees?.app?.amountFormatted || '0',\n )\n const funLpFeesFromAmountBaseUnit = BigInt(fees?.app?.amount || '0')\n\n // Relay fees, denominated in source chain token\n const relayLpFeesUsd =\n Number.parseFloat(fees?.relayer?.amountUsd || '0') +\n Number.parseFloat(fees?.relayerGas?.amountUsd || '0') +\n Number.parseFloat(fees?.relayerService?.amountUsd || '0')\n const relayLpFeesFromAmount =\n Number.parseFloat(fees?.relayer?.amountFormatted || '0') +\n Number.parseFloat(fees?.relayerGas?.amountFormatted || '0') +\n Number.parseFloat(fees?.relayerService?.amountFormatted || '0')\n const relayLpFeesFromAmountBaseUnit =\n BigInt(fees?.relayer?.amount || '0') +\n BigInt(fees?.relayerGas?.amount || '0') +\n BigInt(fees?.relayerService?.amount || '0')\n\n const totalLpFeesUsd = funLpFeesUsd + relayLpFeesUsd\n const totalLpFeesFromAmount = funLpFeesFromAmount + relayLpFeesFromAmount\n const totalLpFeesFromAmountBaseUnit =\n funLpFeesFromAmountBaseUnit + relayLpFeesFromAmountBaseUnit\n\n logger.log('parseRelayFees', {\n relayGasFeesUsd,\n funLpFeesUsd,\n funLpFeesFromAmount,\n funLpFeesFromAmountBaseUnit,\n relayLpFeesUsd,\n relayLpFeesFromAmount,\n relayLpFeesFromAmountBaseUnit,\n totalLpFeesUsd,\n totalLpFeesFromAmount,\n totalLpFeesFromAmountBaseUnit,\n })\n\n return {\n relayGasFeesUsd,\n totalLpFeesUsd,\n totalFeesUsd: relayGasFeesUsd + totalLpFeesUsd,\n totalFeesFromAmount: totalLpFeesFromAmount,\n totalFeesFromAmountBaseUnit: totalLpFeesFromAmountBaseUnit,\n }\n}\n", "import { LogLevel } from '@reservoir0x/relay-sdk'\nimport type { Abi, Address } from 'viem'\n\nexport { LogLevel }\n\nexport type RelayExecutionStatus =\n | 'refund'\n | 'delayed'\n | 'waiting'\n | 'failure'\n | 'pending'\n | 'success'\n\n// https://docs.relay.link/references/api/get-intents-status-v2\nexport interface RelayExecutionInfo {\n status: RelayExecutionStatus\n details: string\n /** Incoming transaction hashes */\n inTxHashes: string[]\n /** Outgoing transaction hashes */\n txHashes: string[]\n /** The last timestamp the data was updated in milliseconds */\n time: number\n originChainId: number\n destinationChainId: number\n}\n\n//// The types below are duplicated from @funkit/api-base atm, but this package should be used in BE as well\n//// TODO: Are we fine with BE importing @funkit/api-base and (by extension) @funkit/utils?\n//// See https://linear.app/funxyz/issue/PE-1342/sdk-extract-domainsrelayts-to-a-new-package#comment-d487d533\n\nexport interface Logger {\n error(message: string, data?: object): void\n log(message: string, data?: object): void\n}\n\nexport interface ApiFunkitCheckoutActionParams {\n contractAbi: Abi\n contractAddress: Address\n functionName: string\n functionArgs: unknown[]\n value?: bigint\n}\n\nexport enum CheckoutRefundState {\n INITIATED = 'INITIATED',\n ERROR = 'ERROR',\n REFUNDED = 'REFUNDED',\n PROCEEDED = 'PROCEEDED',\n WAITING_FOR_FULFILLMENT = 'WAITING_FOR_FULFILLMENT',\n FULFILLED = 'FULFILLED',\n}\n\n// Reference from api server: https://github.com/fun-xyz/fun-api-server/blob/main/src/tables/FunWalletCheckout.ts#L11C1-L21C2\nexport enum CheckoutState {\n // In-progress States\n FROM_UNFUNDED = 'FROM_UNFUNDED',\n FROM_FUNDED = 'FROM_FUNDED',\n FROM_POOLED = 'FROM_POOLED',\n TO_UNFUNDED = 'TO_UNFUNDED',\n TO_FUNDED = 'TO_FUNDED',\n TO_POOLED = 'TO_POOLED',\n TO_READY = 'TO_READY',\n PENDING_RECEIVAL = 'PENDING_RECEIVAL',\n // Terminal States\n COMPLETED = 'COMPLETED',\n CHECKOUT_ERROR = 'CHECKOUT_ERROR',\n EXPIRED = 'EXPIRED',\n CANCELLED = 'CANCELLED',\n}\n\n// The response of the actual /checkout/quote api\nexport type CheckoutApiQuoteResponse = {\n quoteId: string\n estTotalFromAmountBaseUnit: string\n estSubtotalFromAmountBaseUnit: string\n estFeesFromAmountBaseUnit: string\n fromTokenAddress: Address\n estFeesUsd: number\n estSubtotalUsd: number\n estTotalUsd: number\n estCheckoutTimeMs: number\n estMarketMakerGasUsd: number\n lpFeePercentage: number\n lpFeeUsd: number\n}\n\n// The formatted response quote interface from the core sdk\nexport type CheckoutQuoteResponse = CheckoutApiQuoteResponse & {\n estTotalFromAmount: string\n estSubtotalFromAmount: string\n estFeesFromAmount: string\n\n // Any additional fields purely for frontend use\n metadata?: { [key: string]: unknown }\n}\n", "import type { Address } from 'viem'\nimport {\n FUNKIT_NATIVE_TOKEN,\n RELAY_NATIVE_TOKEN,\n RELAY_TERMINAL_STATUSES,\n} from './constants'\nimport {\n CheckoutRefundState,\n CheckoutState,\n type RelayExecutionInfo,\n} from './types'\n\n/**\n * Converts a token address within Funkit the corresponding Relay token address.\n */\nexport function convertFunToRelayTokenAddress(address: Address): Address {\n if (address.toLowerCase() === FUNKIT_NATIVE_TOKEN.toLowerCase()) {\n return RELAY_NATIVE_TOKEN\n }\n\n return address\n}\n\nexport function getRelayExecutionRefundState(\n info: RelayExecutionInfo,\n): CheckoutRefundState | undefined {\n switch (info.status) {\n case 'refund':\n return CheckoutRefundState.REFUNDED\n default:\n return undefined\n }\n}\n\nexport function getRelayExecutionState(\n info: RelayExecutionInfo,\n): CheckoutState {\n switch (info.status) {\n case 'success':\n return CheckoutState.COMPLETED\n case 'failure':\n case 'refund':\n return CheckoutState.CHECKOUT_ERROR\n default:\n return CheckoutState.PENDING_RECEIVAL\n }\n}\n\n/**\n * Checks whether the Relay execution has reached a terminal status.\n */\nexport function isRelayExecutionTerminalStatus(\n info: RelayExecutionInfo,\n): boolean {\n return RELAY_TERMINAL_STATUSES.includes(info.status)\n}\n"],
5
- "mappings": ";;;;;;;;;;;;;;;;;;;;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;;;ACAA,uBAOO;AAgBA,SAAS,sBAAsB;AAAA,EACpC;AAAA,EACA;AAAA,EACA,GAAG;AACL,GAA6C;AAC3C,aAAO,+BAAa;AAAA,IAClB,GAAG;AAAA,IACH,YAAY;AAAA,IACZ,QAAQ,OAAO,IAAI,6CAA4B;AAAA,IAC/C,QAAQ,CAAC,YAAY;AACnB,aAAO,IAAI,kBAAkB,OAAO;AAAA,IACtC;AAAA,EACF,CAAC;AACH;AAKO,SAAS,iBAA8B;AAC5C,QAAM,aAAS,4BAAU;AAEzB,MAAI,CAAC,QAAQ;AACX,UAAM,IAAI,MAAM,6BAA6B;AAAA,EAC/C;AAEA,SAAO;AACT;;;ACjDA,IAAAA,oBAAgD;AAehD,eAAsB,kBAAkB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAA4B;AAC1B,QAAM,eAAe,EAAE,QAAQ,QAAQ;AAAA,IACrC,OAAO;AAAA,IACP,QAAQ;AAAA,IACR,YAAY,OAAO;AAAA,MACjB;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,MAAM;AACJ,YAAM,YAAY;AAClB,aAAO,IAAI,GAAG,SAAS,WAAW;AAAA,QAChC;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,MACF,CAAC;AAED,wBAAkB,aAAa,UAAU,EAAE;AAE3C,UAAI,OAAO;AACT,eAAO,IAAI,GAAG,SAAS,kBAAkB,KAAK;AAC9C,cAAM,QAAQ,KAAK,EAAE,MAAM,CAAC,MAAM;AAChC,iBAAO,MAAM,GAAG,SAAS,kBAAkB,CAAC;AAAA,QAC9C,CAAC;AAAA,MACH;AAAA;AAAA;AAAA,QAGE,YACA,SAAS,SAAS,KAClB,SAAS,WAAW,MAAM;AAAA,QAC1B;AACA,eAAO,IAAI,GAAG,SAAS,cAAc,QAAQ;AAG7C,cAAM,YAAY,SAAS,CAAC,EAAE,MAAa,EAAE,MAAM,CAAC,MAAM;AACxD,iBAAO,MAAM,GAAG,SAAS,sBAAsB,CAAC;AAAA,QAClD,CAAC;AAAA,MACH;AAAA,IACF;AAAA,EACF,CAAC;AACH;AAEA,eAAsB,sBACpB,WAC6B;AAC7B,QAAM,MAAM,GAAG,mCAAiB,gCAAgC,SAAS;AACzE,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,MAAM,SAAS,UAAU;AAAA,EACjC;AAEA,QAAM,OAAO,MAAM,SAAS,KAAK;AACjC,SAAO;AACT;;;ACpFA,kBAAiD;;;ACM1C,IAAM,sBACX;AAKK,IAAM,qBACX;AAKK,IAAM,2BACX;AAKK,IAAM,qBAAqB;AAK3B,IAAM,sCAAsC;AAE5C,IAAM,0BAAkD;AAAA,EAC7D;AAAA,EACA;AAAA,EACA;AACF;;;AChCO,SAAS,sBAAsB;AAAA,EACpC;AACF,GAEW;AAGT,SAAO,cAAc,IAAI;AAC3B;AAEO,SAAS,eAAe;AAAA,EAC7B;AAAA,EACA;AACF,GAGG;AAED,QAAM,kBAAkB,OAAO,WAAW,MAAM,KAAK,aAAa,GAAG;AAGrE,QAAM,eAAe,OAAO,WAAW,MAAM,KAAK,aAAa,GAAG;AAClE,QAAM,sBAAsB,OAAO;AAAA,IACjC,MAAM,KAAK,mBAAmB;AAAA,EAChC;AACA,QAAM,8BAA8B,OAAO,MAAM,KAAK,UAAU,GAAG;AAGnE,QAAM,iBACJ,OAAO,WAAW,MAAM,SAAS,aAAa,GAAG,IACjD,OAAO,WAAW,MAAM,YAAY,aAAa,GAAG,IACpD,OAAO,WAAW,MAAM,gBAAgB,aAAa,GAAG;AAC1D,QAAM,wBACJ,OAAO,WAAW,MAAM,SAAS,mBAAmB,GAAG,IACvD,OAAO,WAAW,MAAM,YAAY,mBAAmB,GAAG,IAC1D,OAAO,WAAW,MAAM,gBAAgB,mBAAmB,GAAG;AAChE,QAAM,gCACJ,OAAO,MAAM,SAAS,UAAU,GAAG,IACnC,OAAO,MAAM,YAAY,UAAU,GAAG,IACtC,OAAO,MAAM,gBAAgB,UAAU,GAAG;AAE5C,QAAM,iBAAiB,eAAe;AACtC,QAAM,wBAAwB,sBAAsB;AACpD,QAAM,gCACJ,8BAA8B;AAEhC,SAAO,IAAI,kBAAkB;AAAA,IAC3B;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC;AAED,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,cAAc,kBAAkB;AAAA,IAChC,qBAAqB;AAAA,IACrB,6BAA6B;AAAA,EAC/B;AACF;;;ACrEA,IAAAC,oBAAyB;;;ACelB,SAAS,8BAA8B,SAA2B;AACvE,MAAI,QAAQ,YAAY,MAAM,oBAAoB,YAAY,GAAG;AAC/D,WAAO;AAAA,EACT;AAEA,SAAO;AACT;AAEO,SAAS,6BACd,MACiC;AACjC,UAAQ,KAAK,QAAQ;AAAA,IACnB,KAAK;AACH;AAAA,IACF;AACE,aAAO;AAAA,EACX;AACF;AAEO,SAAS,uBACd,MACe;AACf,UAAQ,KAAK,QAAQ;AAAA,IACnB,KAAK;AACH;AAAA,IACF,KAAK;AAAA,IACL,KAAK;AACH;AAAA,IACF;AACE;AAAA,EACJ;AACF;AAKO,SAAS,+BACd,MACS;AACT,SAAO,wBAAwB,SAAS,KAAK,MAAM;AACrD;;;AJ3BA,eAAsB,cAAc;AAAA,EAClC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,GAAwD;AACtD,MAAI;AACF,UAAM,cAAc,eAAe;AAGnC,UAAM,cAAc,MAAM;AAC1B,UAAM,qBAAqB,OAAO,KAAK,MAAM,gBAAgB,WAAW,CAAC;AACzE,UAAM,2BAA2B,mBAAmB,SAAS;AAE7D,UAAM,MAAM,cAAc,IAAI,CAAC,WAAW;AACxC,YAAM,WAAO,gCAAmB;AAAA,QAC9B,KAAK,OAAO;AAAA,QACZ,MAAM,OAAO;AAAA,QACb,cAAc,OAAO;AAAA,MACvB,CAAC;AAED,aAAO;AAAA,QACL;AAAA,QACA,IAAI,OAAO;AAAA,QACX,OAAO,OAAO,OAAO,SAAS,EAAE;AAAA,MAClC;AAAA,IACF,CAAC;AAED,WAAO,IAAI,uBAAuB;AAAA,MAChC;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA,oBAAoB;AAAA,MACpB;AAAA,IACF,CAAC;AAGD,UAAM,aAAa,MAAM,YAAY,QAAQ,SAAS;AAAA,MACpD,SAAS,OAAO,WAAW;AAAA,MAC3B,WAAW,OAAO,SAAS;AAAA,MAC3B,UAAU,8BAA8B,gBAAgB;AAAA,MACxD,YAAY,8BAA8B,cAAc;AAAA,MACxD,QAAQ;AAAA,MACR,WAAW;AAAA,MACX,WAAW;AAAA,MACX,MAAM;AAAA,MACN,GAAI,OAAO,EAAE,IAAI;AAAA,MACjB,SAAS;AAAA,QACP,UAAU;AAAA,QACV,SAAS;AAAA,UACP;AAAA,YACE,KAAK,sBAAsB;AAAA,cACzB,aACE,gBAAgB,aAChB,iBAAiB,YAAY,MAAM,eAAe,YAAY;AAAA,YAClE,CAAC,EAAE,SAAS;AAAA,YACZ,WAAW;AAAA,UACb;AAAA,QACF;AAAA,MACF;AAAA,IACF,CAAC;AAID,WAAO,IAAI,cAAc,UAAU;AAEnC,UAAM,iBAAiB;AAAA,MACrB,WAAW,SAAS,aAAa,aAAa;AAAA,IAChD;AACA,UAAM,cAAc,OAAO,WAAW,SAAS,YAAY,aAAa,CAAC;AAEzE,UAAM,mBACJ,WAAW,SAAS,YAAY,mBAAmB;AACrD,UAAM,2BACJ,WAAW,SAAS,YAAY,UAAU;AAI5C,UAAM,iBAAiB,WAAW,MAAM,CAAC,GAAG;AAG5C,QAAI,CAAC,gBAAgB;AACnB,YAAM,IAAI,MAAM,0CAA0C;AAAA,IAC5D;AAEA,UAAM;AAAA,MACJ;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,MACA;AAAA,IACF,IAAI,eAAe,EAAE,MAAM,WAAW,MAAM,OAAO,CAAC;AAEpD,UAAM,yBACJ,OAAO,WAAW,gBAAgB,IAAI,qBACtC,SAAS;AAEX,UAAM,iCACJ,OAAO,wBAAwB,IAAI,6BACnC,SAAS;AAEX,WAAO;AAAA,MACL,SAAS;AAAA,MACT,oBAAoB;AAAA,MACpB;AAAA,MACA,4BAA4B;AAAA,MAC5B;AAAA,MACA,mBAAmB,oBAAoB,SAAS;AAAA,MAChD,2BAA2B,4BAA4B,SAAS;AAAA,MAChE;AAAA,MACA,YAAY;AAAA,MACZ;AAAA,MACA;AAAA,MACA,oBACG,WAAW,SAAS,gBAAgB,KAAK,MAC1C;AAAA,MACF,sBAAsB;AAAA,MACtB,iBAAiB;AAAA;AAAA,MACjB,UAAU;AAAA,MACV,UAAU;AAAA,QACR;AAAA,QACA,kBAAkB;AAAA,MACpB;AAAA,IACF;AAAA,EACF,SAAS,KAAK;AACZ,UAAM,IAAI;AAAA,MACR,sDACE,eAAe,QAAQ,IAAI,UAAU,KAAK,UAAU,GAAG,CACzD;AAAA,IACF;AAAA,EACF;AACF;",
6
- "names": ["import_relay_sdk", "import_relay_sdk"]
3
+ "sources": ["../index.ts", "../src/client.ts", "../src/types.ts", "../src/constants.ts", "../src/execution.ts", "../src/fees.ts", "../src/price.ts", "../src/quote.ts", "../src/utils.ts"],
4
+ "sourcesContent": ["export {\n getRelayClient,\n initializeRelayClient,\n type InitializeRelayClientParams,\n} from './src/client'\nexport {\n FUN_RELAY_REFERRER,\n FUN_RELAY_REVENUE_WALLET,\n RELAY_TERMINAL_STATUSES,\n} from './src/constants'\nexport {\n type ExecuteRelayQuoteParams,\n executeRelayQuote,\n getRelayExecutionInfo,\n} from './src/execution'\nexport {\n computeFunRelayFeeBps,\n parseRelayFees,\n} from './src/fees'\nexport { getRelayAssetPriceInfo } from './src/price'\nexport {\n type GetRelayQuoteParams,\n getRelayQuote,\n type RelayQuote,\n} from './src/quote'\nexport {\n getRelayExecutionRefundState,\n getRelayExecutionState,\n isRelayExecutionTerminalStatus,\n convertFunToRelayTokenAddress,\n} from './src/utils'\nexport {\n LogLevel,\n type RelayExecutionInfo,\n type RelayExecutionStatus,\n type RelayTokenPriceInfo,\n} from './src/types'\n", "import {\n MAINNET_RELAY_API,\n type RelayClient,\n type RelayClientOptions,\n convertViemChainToRelayChain,\n createClient,\n getClient,\n} from '@reservoir0x/relay-sdk'\nimport type { Chain } from 'viem'\nimport type { Logger } from './types'\n\nexport type InitializeRelayClientParams = Omit<\n RelayClientOptions,\n 'baseApiUrl' | 'chains' | 'logger'\n> & {\n chains: Chain[]\n logger: Logger\n}\n\n/**\n * Initializes a global instance of the RelayClient\n * https://docs.relay.link/references/sdk/createClient\n */\nexport function initializeRelayClient({\n chains,\n logger,\n ...options\n}: InitializeRelayClientParams): RelayClient {\n return createClient({\n ...options,\n baseApiUrl: MAINNET_RELAY_API,\n chains: chains.map(convertViemChainToRelayChain),\n logger: (message) => {\n logger.info('[RelayClient]:', message)\n },\n })\n}\n\n/**\n * Gets the global instance of the RelayClient\n */\nexport function getRelayClient(): RelayClient {\n const client = getClient()\n\n if (!client) {\n throw new Error('Relay client is not defined')\n }\n\n return client\n}\n", "import { LogLevel } from '@reservoir0x/relay-sdk'\nimport type { Abi, Address } from 'viem'\n\nexport { LogLevel }\n\n// https://docs.relay.link/references/api/get-intents-status-v2\nexport interface RelayExecutionInfo {\n status: RelayExecutionStatus\n details: string\n /** Incoming transaction hashes */\n inTxHashes: string[]\n /** Outgoing transaction hashes */\n txHashes: string[]\n /** The last timestamp the data was updated in milliseconds */\n time: number\n originChainId: number\n destinationChainId: number\n}\n\n// https://docs.relay.link/references/api/get-token-price\nexport interface RelayTokenPriceInfo {\n price: number\n}\n\n//// The types below are duplicated from @funkit/api-base atm, but this package should be used in BE as well\n//// TODO: Are we fine with BE importing @funkit/api-base and (by extension) @funkit/utils?\n//// See https://linear.app/funxyz/issue/PE-1342/sdk-extract-domainsrelayts-to-a-new-package#comment-d487d533\n\nexport interface Logger {\n error(message: string, data?: object): void\n info(message: string, data?: object): void\n}\n\n// Reference: https://github.com/reservoirprotocol/relay-kit/blob/211c645f9702a3b459ff545aa4e2e9d536c38455/packages/sdk/src/types/Execute.ts#L54-L61\nexport enum RelayExecutionStatus {\n DELAYED = 'delayed',\n FAILURE = 'failure',\n PENDING = 'pending',\n REFUND = 'refund',\n SUCCESS = 'success',\n WAITING = 'waiting',\n UNKNOWN = 'unknown',\n}\n\nexport interface ApiFunkitCheckoutActionParams {\n contractAbi: Abi\n contractAddress: Address\n functionName: string\n functionArgs: unknown[]\n value?: bigint\n}\n\nexport enum CheckoutRefundState {\n INITIATED = 'INITIATED',\n ERROR = 'ERROR',\n REFUNDED = 'REFUNDED',\n PROCEEDED = 'PROCEEDED',\n WAITING_FOR_FULFILLMENT = 'WAITING_FOR_FULFILLMENT',\n FULFILLED = 'FULFILLED',\n}\n\n// Reference from api server: https://github.com/fun-xyz/fun-api-server/blob/main/src/tables/FunWalletCheckout.ts#L11C1-L21C2\nexport enum CheckoutState {\n // In-progress States\n FROM_UNFUNDED = 'FROM_UNFUNDED',\n FROM_FUNDED = 'FROM_FUNDED',\n FROM_POOLED = 'FROM_POOLED',\n TO_UNFUNDED = 'TO_UNFUNDED',\n TO_FUNDED = 'TO_FUNDED',\n TO_POOLED = 'TO_POOLED',\n TO_READY = 'TO_READY',\n PENDING_RECEIVAL = 'PENDING_RECEIVAL',\n // Terminal States\n COMPLETED = 'COMPLETED',\n CHECKOUT_ERROR = 'CHECKOUT_ERROR',\n EXPIRED = 'EXPIRED',\n CANCELLED = 'CANCELLED',\n}\n\n// The response of the actual /checkout/quote api\nexport type CheckoutApiQuoteResponse = {\n quoteId: string\n estTotalFromAmountBaseUnit: string\n estSubtotalFromAmountBaseUnit: string\n estFeesFromAmountBaseUnit: string\n fromTokenAddress: Address\n estFeesUsd: number\n estSubtotalUsd: number\n estTotalUsd: number\n estCheckoutTimeMs: number\n estMarketMakerGasUsd: number\n lpFeePercentage: number\n lpFeeUsd: number\n}\n\n// The formatted response quote interface from the core sdk\nexport type CheckoutQuoteResponse = CheckoutApiQuoteResponse & {\n estTotalFromAmount: string\n estSubtotalFromAmount: string\n estFeesFromAmount: string\n\n // Any additional fields purely for frontend use\n metadata?: { [key: string]: unknown }\n}\n", "import type { Address } from 'viem'\nimport { RelayExecutionStatus } from './types'\n\n/**\n * Fake address for a chain's native currency used by Funkit\n */\nexport const FUNKIT_NATIVE_TOKEN =\n '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' satisfies Address\n\n/**\n * Fake address for a chain's native currency used by Relay\n */\nexport const RELAY_NATIVE_TOKEN =\n '0x0000000000000000000000000000000000000000' satisfies Address\n\n/**\n * Wallet that receives the app fees collected by Relay\n */\nexport const FUN_RELAY_REVENUE_WALLET =\n '0xb61562d83aEC43a050A06BED12Ac2bD8f9BFfd5E' satisfies Address\n\n/**\n * Referred field in Relay quote\n */\nexport const FUN_RELAY_REFERRER = 'funxyz'\n\n/**\n * Buffer added to Relay's time estimate (which sometimes is 0)\n */\nexport const RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 3_000 // 3 seconds\n\nexport const RELAY_TERMINAL_STATUSES: RelayExecutionStatus[] = [\n RelayExecutionStatus.REFUND,\n RelayExecutionStatus.FAILURE,\n RelayExecutionStatus.SUCCESS,\n]\n", "import {\n type Execute,\n MAINNET_RELAY_API,\n type ProgressData,\n} from '@reservoir0x/relay-sdk'\nimport type { Hex, WalletClient } from 'viem'\nimport { getRelayClient } from './client'\nimport type { Logger, RelayExecutionInfo } from './types'\n\nexport type RelayExecutionStep = ProgressData['currentStep'] & {}\n\nexport interface ExecuteRelayQuoteParams {\n logger: Logger\n onConfirmed: (txHash: Hex) => Promise<void>\n onError: (error: Error) => Promise<void>\n onProgress?: (step: RelayExecutionStep | null) => void\n relayQuote: Execute\n walletClient: WalletClient\n}\n\nexport async function executeRelayQuote({\n logger,\n onConfirmed,\n onError,\n onProgress,\n relayQuote,\n walletClient,\n}: ExecuteRelayQuoteParams) {\n await getRelayClient().actions.execute({\n quote: relayQuote,\n wallet: walletClient,\n onProgress: async ({\n steps,\n fees,\n breakdown,\n currentStep,\n currentStepItem,\n txHashes,\n details,\n error,\n }) => {\n const logPrefix = 'onRelayProgress'\n logger.info(`${logPrefix}:params`, {\n steps,\n currentStep,\n fees,\n breakdown,\n currentStepItem,\n txHashes,\n details,\n error,\n })\n\n onProgress?.(currentStep ?? null)\n\n if (error) {\n logger.info(`${logPrefix}:errorDetected`, error)\n await onError(error).catch((e) => {\n logger.error(`${logPrefix}:onErrorFailed`, e)\n })\n } else if (\n // We can redirect as soon as all the required user steps are done\n // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1748381169792379\n txHashes &&\n txHashes.length > 0 &&\n txHashes.length === steps.length\n ) {\n logger.info(`${logPrefix}:completed`, txHashes)\n // Can we assume its completed here?\n // Use first txHash as the main txHash in fun DE table\n await onConfirmed(txHashes[0].txHash as Hex).catch((e) => {\n logger.error(`${logPrefix}:onConfirmedFailed`, e)\n })\n }\n },\n })\n}\n\nexport async function getRelayExecutionInfo(\n requestId: string,\n): Promise<RelayExecutionInfo> {\n const url = `${MAINNET_RELAY_API}/intents/status/v2?requestId=${requestId}`\n const response = await fetch(url)\n if (!response.ok) {\n throw Error(response.statusText)\n }\n\n const data = await response.json()\n return data as RelayExecutionInfo\n}\n", "import type { CallFees } from '@reservoir0x/relay-sdk'\nimport type { Logger } from './types'\n\nexport function computeFunRelayFeeBps({\n isSameToken,\n}: {\n isSameToken: boolean\n}): number {\n // For now, we have a flat 2bps app fee for all relay transactions\n // TODO: Dynamic fee based on the transaction size, from token, to token, etc\n return isSameToken ? 0 : 2\n}\n\nexport function parseRelayFees({\n fees,\n logger,\n}: {\n fees: CallFees | undefined\n logger: Logger\n}) {\n // Gas fees, denominated in source chain native token\n const relayGasFeesUsd = Number.parseFloat(fees?.gas?.amountUsd || '0')\n\n // App fees, denominated in source chain token\n const funLpFeesUsd = Number.parseFloat(fees?.app?.amountUsd || '0')\n const funLpFeesFromAmount = Number.parseFloat(\n fees?.app?.amountFormatted || '0',\n )\n const funLpFeesFromAmountBaseUnit = BigInt(fees?.app?.amount || '0')\n\n // Relay fees, denominated in source chain token\n const relayLpFeesUsd =\n Number.parseFloat(fees?.relayer?.amountUsd || '0') +\n Number.parseFloat(fees?.relayerGas?.amountUsd || '0') +\n Number.parseFloat(fees?.relayerService?.amountUsd || '0')\n const relayLpFeesFromAmount =\n Number.parseFloat(fees?.relayer?.amountFormatted || '0') +\n Number.parseFloat(fees?.relayerGas?.amountFormatted || '0') +\n Number.parseFloat(fees?.relayerService?.amountFormatted || '0')\n const relayLpFeesFromAmountBaseUnit =\n BigInt(fees?.relayer?.amount || '0') +\n BigInt(fees?.relayerGas?.amount || '0') +\n BigInt(fees?.relayerService?.amount || '0')\n\n const totalLpFeesUsd = funLpFeesUsd + relayLpFeesUsd\n const totalLpFeesFromAmount = funLpFeesFromAmount + relayLpFeesFromAmount\n const totalLpFeesFromAmountBaseUnit =\n funLpFeesFromAmountBaseUnit + relayLpFeesFromAmountBaseUnit\n\n logger.info('parseRelayFees', {\n relayGasFeesUsd,\n funLpFeesUsd,\n funLpFeesFromAmount,\n funLpFeesFromAmountBaseUnit,\n relayLpFeesUsd,\n relayLpFeesFromAmount,\n relayLpFeesFromAmountBaseUnit,\n totalLpFeesUsd,\n totalLpFeesFromAmount,\n totalLpFeesFromAmountBaseUnit,\n })\n\n return {\n relayGasFeesUsd,\n totalLpFeesUsd,\n totalFeesUsd: relayGasFeesUsd + totalLpFeesUsd,\n totalFeesFromAmount: totalLpFeesFromAmount,\n totalFeesFromAmountBaseUnit: totalLpFeesFromAmountBaseUnit,\n }\n}\n", "import { MAINNET_RELAY_API } from '@reservoir0x/relay-sdk'\nimport type { RelayTokenPriceInfo } from './types'\n\nexport async function getRelayAssetPriceInfo({\n chainId,\n address,\n}: {\n chainId: string\n address: string\n}): Promise<RelayTokenPriceInfo> {\n const url = `${MAINNET_RELAY_API}/currencies/token/price?chainId=${chainId}&address=${address}`\n const response = await fetch(url)\n if (!response.ok) {\n throw Error(response.statusText)\n }\n\n const data = await response.json()\n return data as RelayTokenPriceInfo\n}\n", "import type { Execute, GetQuoteParameters } from '@reservoir0x/relay-sdk'\nimport { type Address, encodeFunctionData } from 'viem'\nimport { getRelayClient } from './client'\nimport {\n FUN_RELAY_REFERRER,\n FUN_RELAY_REVENUE_WALLET,\n RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,\n} from './constants'\nimport { computeFunRelayFeeBps, parseRelayFees } from './fees'\nimport type {\n ApiFunkitCheckoutActionParams,\n CheckoutQuoteResponse,\n Logger,\n} from './types'\nimport { convertFunToRelayTokenAddress } from './utils'\n\ntype RelayQuoteOptions = GetQuoteParameters['options'] & {}\n\nexport type GetRelayQuoteParams = {\n actionParams?: ApiFunkitCheckoutActionParams[]\n fromChainId: string\n fromTokenAddress: Address\n logger: Logger\n /**\n * {@link getRelayQuote} already sets {@link RelayQuoteOptions.appFees|appFees} and {@link RelayQuoteOptions.referrer|referrer}.\n * Only include them if you wish to override.\n */\n options?: RelayQuoteOptions\n recipientAddress: Address | undefined\n toChainId: string\n toTokenAddress: Address\n tradeType: 'EXACT_INPUT' | 'EXACT_OUTPUT'\n userAddress: Address | undefined\n} & (\n | {\n fromTokenAmountBaseUnit: bigint | string\n tradeType: 'EXACT_INPUT'\n }\n | {\n toTokenAmountBaseUnit: bigint | string\n tradeType: 'EXACT_OUTPUT'\n }\n)\n\nexport type RelayQuote = CheckoutQuoteResponse & {\n /** Required for EXACT_INPUT checkouts */\n finalToAmountBaseUnit: string\n metadata: {\n fromAmountBaseUnit: string\n relayQuote: Execute\n toAmountBaseUnit: string\n }\n}\n\nexport async function getRelayQuote({\n logger,\n ...params\n}: GetRelayQuoteParams): Promise<RelayQuote> {\n const {\n actionParams,\n fromChainId,\n fromTokenAddress,\n options,\n recipientAddress,\n toChainId,\n toTokenAddress,\n userAddress,\n } = params\n\n try {\n const relayClient = getRelayClient()\n\n const tokenAmountBaseUnit =\n params.tradeType === 'EXACT_INPUT'\n ? params.fromTokenAmountBaseUnit\n : params.toTokenAmountBaseUnit\n\n const txs = actionParams?.map((action) => {\n const data = encodeFunctionData({\n abi: action.contractAbi,\n args: action.functionArgs,\n functionName: action.functionName,\n })\n\n return {\n data,\n to: action.contractAddress,\n value: String(action.value ?? 0n),\n }\n })\n\n logger.info('getRelayQuoteParams', {\n ...params,\n tokenAmountBaseUnit,\n txs,\n })\n\n // Get the relay quote\n const relayQuote = await relayClient.actions.getQuote({\n chainId: Number(fromChainId),\n toChainId: Number(toChainId),\n currency: convertFunToRelayTokenAddress(fromTokenAddress),\n toCurrency: convertFunToRelayTokenAddress(toTokenAddress),\n amount: tokenAmountBaseUnit.toString(),\n recipient: recipientAddress,\n tradeType: params.tradeType,\n user: userAddress,\n ...(txs && { txs }),\n options: {\n referrer: FUN_RELAY_REFERRER,\n appFees: [\n {\n fee: computeFunRelayFeeBps({\n isSameToken:\n fromChainId === toChainId &&\n fromTokenAddress.toLowerCase() === toTokenAddress.toLowerCase(),\n }).toString(),\n recipient: FUN_RELAY_REVENUE_WALLET,\n },\n ],\n ...options,\n },\n })\n\n // TODO: Handling for no route response\n\n logger.info('relayQuote', relayQuote)\n\n const estSubtotalUsd = Number(\n relayQuote.details?.currencyOut?.amountUsd || 0,\n )\n const estTotalUsd = Number(relayQuote.details?.currencyIn?.amountUsd || 0)\n // Get how much fromAmount is needed for the quote\n const fromAmountString =\n relayQuote.details?.currencyIn?.amountFormatted || '0'\n const fromAmountBaseUnitString =\n relayQuote.details?.currencyIn?.amount || '0'\n\n // RequestID will be consistent across steps in the quote\n // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1747774944603209\n const relayRequestId = relayQuote.steps[0]?.requestId\n\n // TODO: Verify with relay team if this is possible?\n if (!relayRequestId) {\n throw new Error('Relay quote does not contain a requestId')\n }\n\n // TODO: Verify with relay team if this is possible?\n if (!relayQuote.details?.currencyIn || !relayQuote.details?.currencyOut) {\n throw new Error('Relay quote does not contain trade details')\n }\n\n const {\n relayGasFeesUsd,\n totalLpFeesUsd,\n totalFeesUsd,\n totalFeesFromAmount,\n totalFeesFromAmountBaseUnit,\n } = parseRelayFees({ fees: relayQuote.fees, logger })\n\n const estSubtotalFromAmount = (\n Number.parseFloat(fromAmountString) - totalFeesFromAmount\n ).toString()\n\n const estSubtotalFromAmountBaseUnit = (\n BigInt(fromAmountBaseUnitString) - totalFeesFromAmountBaseUnit\n ).toString()\n\n return {\n quoteId: relayRequestId,\n estCheckoutTimeMs:\n (relayQuote.details.timeEstimate || 0) * 1000 +\n RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,\n estFeesFromAmount: totalFeesFromAmount.toString(),\n estFeesFromAmountBaseUnit: totalFeesFromAmountBaseUnit.toString(),\n estFeesUsd: totalFeesUsd,\n estMarketMakerGasUsd: relayGasFeesUsd,\n estSubtotalFromAmount,\n estSubtotalFromAmountBaseUnit,\n estSubtotalUsd,\n estTotalFromAmount: fromAmountString,\n estTotalFromAmountBaseUnit: fromAmountBaseUnitString,\n estTotalUsd,\n finalToAmountBaseUnit: relayQuote.details.currencyOut.amount ?? '0', // TODO: Or do we want 'minimumAmount'?\n fromTokenAddress,\n lpFeePercentage: 0, // TODO: ?\n lpFeeUsd: totalLpFeesUsd,\n metadata: {\n fromAmountBaseUnit:\n params.tradeType === 'EXACT_INPUT'\n ? tokenAmountBaseUnit.toString()\n : (relayQuote.details.currencyIn.amount ?? '0'),\n relayQuote,\n toAmountBaseUnit:\n params.tradeType === 'EXACT_INPUT'\n ? (relayQuote.details.currencyOut.amount ?? '0')\n : tokenAmountBaseUnit.toString(),\n },\n }\n } catch (err) {\n throw new Error(\n `An error occurred trying to generate a relay quote: ${\n err instanceof Error ? err.message : JSON.stringify(err)\n }`,\n )\n }\n}\n", "import type { Address } from 'viem'\nimport {\n FUNKIT_NATIVE_TOKEN,\n RELAY_NATIVE_TOKEN,\n RELAY_TERMINAL_STATUSES,\n} from './constants'\nimport {\n CheckoutRefundState,\n CheckoutState,\n type RelayExecutionInfo,\n} from './types'\n\n/**\n * Converts a token address within Funkit the corresponding Relay token address.\n */\nexport function convertFunToRelayTokenAddress(address: Address): Address {\n if (address.toLowerCase() === FUNKIT_NATIVE_TOKEN.toLowerCase()) {\n return RELAY_NATIVE_TOKEN\n }\n\n return address\n}\n\nexport function getRelayExecutionRefundState(\n info: RelayExecutionInfo,\n): CheckoutRefundState | undefined {\n switch (info.status) {\n case 'refund':\n return CheckoutRefundState.REFUNDED\n default:\n return undefined\n }\n}\n\nexport function getRelayExecutionState(\n info: RelayExecutionInfo,\n): CheckoutState {\n switch (info.status) {\n case 'success':\n return CheckoutState.COMPLETED\n case 'failure':\n case 'refund':\n return CheckoutState.CHECKOUT_ERROR\n default:\n return CheckoutState.PENDING_RECEIVAL\n }\n}\n\n/**\n * Checks whether the Relay execution has reached a terminal status.\n */\nexport function isRelayExecutionTerminalStatus(\n info: RelayExecutionInfo,\n): boolean {\n return RELAY_TERMINAL_STATUSES.includes(info.status)\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["import_relay_sdk", "import_relay_sdk", "import_relay_sdk"]
7
7
  }
package/dist/index.mjs CHANGED
@@ -15,7 +15,7 @@ function initializeRelayClient({
15
15
  baseApiUrl: MAINNET_RELAY_API,
16
16
  chains: chains.map(convertViemChainToRelayChain),
17
17
  logger: (message) => {
18
- logger.log("[RelayClient]:", message);
18
+ logger.info("[RelayClient]:", message);
19
19
  }
20
20
  });
21
21
  }
@@ -27,14 +27,31 @@ function getRelayClient() {
27
27
  return client;
28
28
  }
29
29
 
30
+ // src/types.ts
31
+ import { LogLevel } from "@reservoir0x/relay-sdk";
32
+
33
+ // src/constants.ts
34
+ var FUNKIT_NATIVE_TOKEN = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
35
+ var RELAY_NATIVE_TOKEN = "0x0000000000000000000000000000000000000000";
36
+ var FUN_RELAY_REVENUE_WALLET = "0xb61562d83aEC43a050A06BED12Ac2bD8f9BFfd5E";
37
+ var FUN_RELAY_REFERRER = "funxyz";
38
+ var RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 3e3;
39
+ var RELAY_TERMINAL_STATUSES = [
40
+ "refund" /* REFUND */,
41
+ "failure" /* FAILURE */,
42
+ "success" /* SUCCESS */
43
+ ];
44
+
30
45
  // src/execution.ts
31
- import { MAINNET_RELAY_API as MAINNET_RELAY_API2 } from "@reservoir0x/relay-sdk";
46
+ import {
47
+ MAINNET_RELAY_API as MAINNET_RELAY_API2
48
+ } from "@reservoir0x/relay-sdk";
32
49
  async function executeRelayQuote({
33
50
  logger,
34
51
  onConfirmed,
35
52
  onError,
53
+ onProgress,
36
54
  relayQuote,
37
- stepMessageSetter,
38
55
  walletClient
39
56
  }) {
40
57
  await getRelayClient().actions.execute({
@@ -51,7 +68,7 @@ async function executeRelayQuote({
51
68
  error
52
69
  }) => {
53
70
  const logPrefix = "onRelayProgress";
54
- logger.log(`${logPrefix}:params`, {
71
+ logger.info(`${logPrefix}:params`, {
55
72
  steps,
56
73
  currentStep,
57
74
  fees,
@@ -61,9 +78,9 @@ async function executeRelayQuote({
61
78
  details,
62
79
  error
63
80
  });
64
- stepMessageSetter(currentStep?.action ?? "");
81
+ onProgress?.(currentStep ?? null);
65
82
  if (error) {
66
- logger.log(`${logPrefix}:errorDetected`, error);
83
+ logger.info(`${logPrefix}:errorDetected`, error);
67
84
  await onError(error).catch((e) => {
68
85
  logger.error(`${logPrefix}:onErrorFailed`, e);
69
86
  });
@@ -72,7 +89,7 @@ async function executeRelayQuote({
72
89
  // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1748381169792379
73
90
  txHashes && txHashes.length > 0 && txHashes.length === steps.length
74
91
  ) {
75
- logger.log(`${logPrefix}:completed`, txHashes);
92
+ logger.info(`${logPrefix}:completed`, txHashes);
76
93
  await onConfirmed(txHashes[0].txHash).catch((e) => {
77
94
  logger.error(`${logPrefix}:onConfirmedFailed`, e);
78
95
  });
@@ -90,21 +107,6 @@ async function getRelayExecutionInfo(requestId) {
90
107
  return data;
91
108
  }
92
109
 
93
- // src/quote.ts
94
- import { encodeFunctionData } from "viem";
95
-
96
- // src/constants.ts
97
- var FUNKIT_NATIVE_TOKEN = "0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee";
98
- var RELAY_NATIVE_TOKEN = "0x0000000000000000000000000000000000000000";
99
- var FUN_RELAY_REVENUE_WALLET = "0xb61562d83aEC43a050A06BED12Ac2bD8f9BFfd5E";
100
- var FUN_RELAY_REFERRER = "funxyz";
101
- var RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 3e3;
102
- var RELAY_TERMINAL_STATUSES = [
103
- "refund",
104
- "failure",
105
- "success"
106
- ];
107
-
108
110
  // src/fees.ts
109
111
  function computeFunRelayFeeBps({
110
112
  isSameToken
@@ -127,7 +129,7 @@ function parseRelayFees({
127
129
  const totalLpFeesUsd = funLpFeesUsd + relayLpFeesUsd;
128
130
  const totalLpFeesFromAmount = funLpFeesFromAmount + relayLpFeesFromAmount;
129
131
  const totalLpFeesFromAmountBaseUnit = funLpFeesFromAmountBaseUnit + relayLpFeesFromAmountBaseUnit;
130
- logger.log("parseRelayFees", {
132
+ logger.info("parseRelayFees", {
131
133
  relayGasFeesUsd,
132
134
  funLpFeesUsd,
133
135
  funLpFeesFromAmount,
@@ -148,8 +150,23 @@ function parseRelayFees({
148
150
  };
149
151
  }
150
152
 
151
- // src/types.ts
152
- import { LogLevel } from "@reservoir0x/relay-sdk";
153
+ // src/price.ts
154
+ import { MAINNET_RELAY_API as MAINNET_RELAY_API3 } from "@reservoir0x/relay-sdk";
155
+ async function getRelayAssetPriceInfo({
156
+ chainId,
157
+ address
158
+ }) {
159
+ const url = `${MAINNET_RELAY_API3}/currencies/token/price?chainId=${chainId}&address=${address}`;
160
+ const response = await fetch(url);
161
+ if (!response.ok) {
162
+ throw Error(response.statusText);
163
+ }
164
+ const data = await response.json();
165
+ return data;
166
+ }
167
+
168
+ // src/quote.ts
169
+ import { encodeFunctionData } from "viem";
153
170
 
154
171
  // src/utils.ts
155
172
  function convertFunToRelayTokenAddress(address) {
@@ -183,22 +200,22 @@ function isRelayExecutionTerminalStatus(info) {
183
200
 
184
201
  // src/quote.ts
185
202
  async function getRelayQuote({
186
- actionParams,
187
203
  logger,
188
- toChainId,
189
- toTokenAddress,
190
- toTokenAmount,
191
- toTokenDecimals,
192
- fromChainId,
193
- fromTokenAddress,
194
- recipientAddress,
195
- userAddress
204
+ ...params
196
205
  }) {
206
+ const {
207
+ actionParams,
208
+ fromChainId,
209
+ fromTokenAddress,
210
+ options,
211
+ recipientAddress,
212
+ toChainId,
213
+ toTokenAddress,
214
+ userAddress
215
+ } = params;
197
216
  try {
198
217
  const relayClient = getRelayClient();
199
- const toMultipler = 10 ** toTokenDecimals;
200
- const toAmountBaseUnitBI = BigInt(Math.floor(toTokenAmount * toMultipler));
201
- const toAmountBaseUnitBIString = toAmountBaseUnitBI.toString();
218
+ const tokenAmountBaseUnit = params.tradeType === "EXACT_INPUT" ? params.fromTokenAmountBaseUnit : params.toTokenAmountBaseUnit;
202
219
  const txs = actionParams?.map((action) => {
203
220
  const data = encodeFunctionData({
204
221
  abi: action.contractAbi,
@@ -211,18 +228,9 @@ async function getRelayQuote({
211
228
  value: String(action.value ?? 0n)
212
229
  };
213
230
  });
214
- logger.log("getRelayQuoteParams", {
215
- actionParams,
216
- toChainId,
217
- toTokenAddress,
218
- toTokenAmount,
219
- toTokenDecimals,
220
- fromChainId,
221
- fromTokenAddress,
222
- recipientAddress,
223
- userAddress,
224
- relayClient,
225
- toAmountBaseUnitBI: toAmountBaseUnitBIString,
231
+ logger.info("getRelayQuoteParams", {
232
+ ...params,
233
+ tokenAmountBaseUnit,
226
234
  txs
227
235
  });
228
236
  const relayQuote = await relayClient.actions.getQuote({
@@ -230,9 +238,9 @@ async function getRelayQuote({
230
238
  toChainId: Number(toChainId),
231
239
  currency: convertFunToRelayTokenAddress(fromTokenAddress),
232
240
  toCurrency: convertFunToRelayTokenAddress(toTokenAddress),
233
- amount: toAmountBaseUnitBIString,
241
+ amount: tokenAmountBaseUnit.toString(),
234
242
  recipient: recipientAddress,
235
- tradeType: "EXACT_OUTPUT",
243
+ tradeType: params.tradeType,
236
244
  user: userAddress,
237
245
  ...txs && { txs },
238
246
  options: {
@@ -244,10 +252,11 @@ async function getRelayQuote({
244
252
  }).toString(),
245
253
  recipient: FUN_RELAY_REVENUE_WALLET
246
254
  }
247
- ]
255
+ ],
256
+ ...options
248
257
  }
249
258
  });
250
- logger.log("relayQuote", relayQuote);
259
+ logger.info("relayQuote", relayQuote);
251
260
  const estSubtotalUsd = Number(
252
261
  relayQuote.details?.currencyOut?.amountUsd || 0
253
262
  );
@@ -258,6 +267,9 @@ async function getRelayQuote({
258
267
  if (!relayRequestId) {
259
268
  throw new Error("Relay quote does not contain a requestId");
260
269
  }
270
+ if (!relayQuote.details?.currencyIn || !relayQuote.details?.currencyOut) {
271
+ throw new Error("Relay quote does not contain trade details");
272
+ }
261
273
  const {
262
274
  relayGasFeesUsd,
263
275
  totalLpFeesUsd,
@@ -269,41 +281,51 @@ async function getRelayQuote({
269
281
  const estSubtotalFromAmountBaseUnit = (BigInt(fromAmountBaseUnitString) - totalFeesFromAmountBaseUnit).toString();
270
282
  return {
271
283
  quoteId: relayRequestId,
272
- estTotalFromAmount: fromAmountString,
273
- estSubtotalFromAmount,
274
- estTotalFromAmountBaseUnit: fromAmountBaseUnitString,
275
- estSubtotalFromAmountBaseUnit,
284
+ estCheckoutTimeMs: (relayQuote.details.timeEstimate || 0) * 1e3 + RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,
276
285
  estFeesFromAmount: totalFeesFromAmount.toString(),
277
286
  estFeesFromAmountBaseUnit: totalFeesFromAmountBaseUnit.toString(),
278
- fromTokenAddress,
279
287
  estFeesUsd: totalFeesUsd,
288
+ estMarketMakerGasUsd: relayGasFeesUsd,
289
+ estSubtotalFromAmount,
290
+ estSubtotalFromAmountBaseUnit,
280
291
  estSubtotalUsd,
292
+ estTotalFromAmount: fromAmountString,
293
+ estTotalFromAmountBaseUnit: fromAmountBaseUnitString,
281
294
  estTotalUsd,
282
- estCheckoutTimeMs: (relayQuote.details?.timeEstimate || 0) * 1e3 + RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,
283
- estMarketMakerGasUsd: relayGasFeesUsd,
295
+ finalToAmountBaseUnit: relayQuote.details.currencyOut.amount ?? "0",
296
+ // TODO: Or do we want 'minimumAmount'?
297
+ fromTokenAddress,
284
298
  lpFeePercentage: 0,
285
299
  // TODO: ?
286
300
  lpFeeUsd: totalLpFeesUsd,
287
301
  metadata: {
302
+ fromAmountBaseUnit: params.tradeType === "EXACT_INPUT" ? tokenAmountBaseUnit.toString() : relayQuote.details.currencyIn.amount ?? "0",
288
303
  relayQuote,
289
- toAmountBaseUnit: toAmountBaseUnitBIString
304
+ toAmountBaseUnit: params.tradeType === "EXACT_INPUT" ? relayQuote.details.currencyOut.amount ?? "0" : tokenAmountBaseUnit.toString()
290
305
  }
291
306
  };
292
307
  } catch (err) {
293
308
  throw new Error(
294
- `An error occured trying to generate a relay quote: ${err instanceof Error ? err.message : JSON.stringify(err)}`
309
+ `An error occurred trying to generate a relay quote: ${err instanceof Error ? err.message : JSON.stringify(err)}`
295
310
  );
296
311
  }
297
312
  }
298
313
  export {
314
+ FUN_RELAY_REFERRER,
315
+ FUN_RELAY_REVENUE_WALLET,
299
316
  LogLevel,
317
+ RELAY_TERMINAL_STATUSES,
318
+ computeFunRelayFeeBps,
319
+ convertFunToRelayTokenAddress,
300
320
  executeRelayQuote,
321
+ getRelayAssetPriceInfo,
301
322
  getRelayClient,
302
323
  getRelayExecutionInfo,
303
324
  getRelayExecutionRefundState,
304
325
  getRelayExecutionState,
305
326
  getRelayQuote,
306
327
  initializeRelayClient,
307
- isRelayExecutionTerminalStatus
328
+ isRelayExecutionTerminalStatus,
329
+ parseRelayFees
308
330
  };
309
331
  //# sourceMappingURL=index.mjs.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
- "sources": ["../src/client.ts", "../src/execution.ts", "../src/quote.ts", "../src/constants.ts", "../src/fees.ts", "../src/types.ts", "../src/utils.ts"],
4
- "sourcesContent": ["import {\n MAINNET_RELAY_API,\n type RelayClient,\n type RelayClientOptions,\n convertViemChainToRelayChain,\n createClient,\n getClient,\n} from '@reservoir0x/relay-sdk'\nimport type { Chain } from 'viem'\nimport type { Logger } from './types'\n\nexport type InitializeRelayClientParams = Omit<\n RelayClientOptions,\n 'baseApiUrl' | 'chains' | 'logger'\n> & {\n chains: Chain[]\n logger: Logger\n}\n\n/**\n * Initializes a global instance of the RelayClient\n * https://docs.relay.link/references/sdk/createClient\n */\nexport function initializeRelayClient({\n chains,\n logger,\n ...options\n}: InitializeRelayClientParams): RelayClient {\n return createClient({\n ...options,\n baseApiUrl: MAINNET_RELAY_API,\n chains: chains.map(convertViemChainToRelayChain),\n logger: (message) => {\n logger.log('[RelayClient]:', message)\n },\n })\n}\n\n/**\n * Gets the global instance of the RelayClient\n */\nexport function getRelayClient(): RelayClient {\n const client = getClient()\n\n if (!client) {\n throw new Error('Relay client is not defined')\n }\n\n return client\n}\n", "import { type Execute, MAINNET_RELAY_API } from '@reservoir0x/relay-sdk'\nimport type { Hex, WalletClient } from 'viem'\nimport { getRelayClient } from './client'\nimport type { Logger, RelayExecutionInfo } from './types'\n\nexport interface ExecuteRelayQuoteParams {\n logger: Logger\n onConfirmed: (txHash: Hex) => Promise<void>\n onError: (error: Error) => Promise<void>\n relayQuote: Execute\n stepMessageSetter: (message: string) => void\n walletClient: WalletClient\n}\n\n// TODO: Add unit tests for this once impl is settled\nexport async function executeRelayQuote({\n logger,\n onConfirmed,\n onError,\n relayQuote,\n stepMessageSetter,\n walletClient,\n}: ExecuteRelayQuoteParams) {\n await getRelayClient().actions.execute({\n quote: relayQuote,\n wallet: walletClient,\n onProgress: async ({\n steps,\n fees,\n breakdown,\n currentStep,\n currentStepItem,\n txHashes,\n details,\n error,\n }) => {\n const logPrefix = 'onRelayProgress'\n logger.log(`${logPrefix}:params`, {\n steps,\n currentStep,\n fees,\n breakdown,\n currentStepItem,\n txHashes,\n details,\n error,\n })\n\n stepMessageSetter(currentStep?.action ?? '')\n\n if (error) {\n logger.log(`${logPrefix}:errorDetected`, error)\n await onError(error).catch((e) => {\n logger.error(`${logPrefix}:onErrorFailed`, e)\n })\n } else if (\n // We can redirect as soon as all the required user steps are done\n // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1748381169792379\n txHashes &&\n txHashes.length > 0 &&\n txHashes.length === steps.length\n ) {\n logger.log(`${logPrefix}:completed`, txHashes)\n // Can we assume its completed here?\n // Use first txHash as the main txHash in fun DE table\n await onConfirmed(txHashes[0].txHash as Hex).catch((e) => {\n logger.error(`${logPrefix}:onConfirmedFailed`, e)\n })\n }\n },\n })\n}\n\nexport async function getRelayExecutionInfo(\n requestId: string,\n): Promise<RelayExecutionInfo> {\n const url = `${MAINNET_RELAY_API}/intents/status/v2?requestId=${requestId}`\n const response = await fetch(url)\n if (!response.ok) {\n throw Error(response.statusText)\n }\n\n const data = await response.json()\n return data as RelayExecutionInfo\n}\n", "import { type Address, encodeFunctionData } from 'viem'\nimport { getRelayClient } from './client'\nimport {\n FUN_RELAY_REFERRER,\n FUN_RELAY_REVENUE_WALLET,\n RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,\n} from './constants'\nimport { computeFunRelayFeeBps, parseRelayFees } from './fees'\nimport type {\n ApiFunkitCheckoutActionParams,\n CheckoutQuoteResponse,\n Logger,\n} from './types'\nimport { convertFunToRelayTokenAddress } from './utils'\n\nexport interface GetRelayQuoteParams {\n actionParams?: ApiFunkitCheckoutActionParams[]\n fromChainId: string\n fromTokenAddress: Address\n logger: Logger\n recipientAddress: Address | undefined\n toChainId: string\n toTokenAddress: Address\n toTokenAmount: number\n toTokenDecimals: number\n userAddress: Address | undefined\n}\n\nexport async function getRelayQuote({\n actionParams,\n logger,\n toChainId,\n toTokenAddress,\n toTokenAmount,\n toTokenDecimals,\n fromChainId,\n fromTokenAddress,\n recipientAddress,\n userAddress,\n}: GetRelayQuoteParams): Promise<CheckoutQuoteResponse> {\n try {\n const relayClient = getRelayClient()\n\n // Mirror logic in api-base (this is wrong)\n const toMultipler = 10 ** toTokenDecimals\n const toAmountBaseUnitBI = BigInt(Math.floor(toTokenAmount * toMultipler))\n const toAmountBaseUnitBIString = toAmountBaseUnitBI.toString()\n\n const txs = actionParams?.map((action) => {\n const data = encodeFunctionData({\n abi: action.contractAbi,\n args: action.functionArgs,\n functionName: action.functionName,\n })\n\n return {\n data,\n to: action.contractAddress,\n value: String(action.value ?? 0n),\n }\n })\n\n logger.log('getRelayQuoteParams', {\n actionParams,\n toChainId,\n toTokenAddress,\n toTokenAmount,\n toTokenDecimals,\n fromChainId,\n fromTokenAddress,\n recipientAddress,\n userAddress,\n relayClient,\n toAmountBaseUnitBI: toAmountBaseUnitBIString,\n txs,\n })\n\n // Get the relay quote\n const relayQuote = await relayClient.actions.getQuote({\n chainId: Number(fromChainId),\n toChainId: Number(toChainId),\n currency: convertFunToRelayTokenAddress(fromTokenAddress),\n toCurrency: convertFunToRelayTokenAddress(toTokenAddress),\n amount: toAmountBaseUnitBIString,\n recipient: recipientAddress,\n tradeType: 'EXACT_OUTPUT',\n user: userAddress,\n ...(txs && { txs }),\n options: {\n referrer: FUN_RELAY_REFERRER,\n appFees: [\n {\n fee: computeFunRelayFeeBps({\n isSameToken:\n fromChainId === toChainId &&\n fromTokenAddress.toLowerCase() === toTokenAddress.toLowerCase(),\n }).toString(),\n recipient: FUN_RELAY_REVENUE_WALLET,\n },\n ],\n },\n })\n\n // TODO: Handling for no route response\n\n logger.log('relayQuote', relayQuote)\n\n const estSubtotalUsd = Number(\n relayQuote.details?.currencyOut?.amountUsd || 0,\n )\n const estTotalUsd = Number(relayQuote.details?.currencyIn?.amountUsd || 0)\n // Get how much fromAmount is needed for the quote\n const fromAmountString =\n relayQuote.details?.currencyIn?.amountFormatted || '0'\n const fromAmountBaseUnitString =\n relayQuote.details?.currencyIn?.amount || '0'\n\n // RequestID will be consistent across steps in the quote\n // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1747774944603209\n const relayRequestId = relayQuote.steps[0]?.requestId\n\n // TODO: Verify with relay team if this is possible?\n if (!relayRequestId) {\n throw new Error('Relay quote does not contain a requestId')\n }\n\n const {\n relayGasFeesUsd,\n totalLpFeesUsd,\n totalFeesUsd,\n totalFeesFromAmount,\n totalFeesFromAmountBaseUnit,\n } = parseRelayFees({ fees: relayQuote.fees, logger })\n\n const estSubtotalFromAmount = (\n Number.parseFloat(fromAmountString) - totalFeesFromAmount\n ).toString()\n\n const estSubtotalFromAmountBaseUnit = (\n BigInt(fromAmountBaseUnitString) - totalFeesFromAmountBaseUnit\n ).toString()\n\n return {\n quoteId: relayRequestId,\n estTotalFromAmount: fromAmountString,\n estSubtotalFromAmount,\n estTotalFromAmountBaseUnit: fromAmountBaseUnitString,\n estSubtotalFromAmountBaseUnit: estSubtotalFromAmountBaseUnit,\n estFeesFromAmount: totalFeesFromAmount.toString(),\n estFeesFromAmountBaseUnit: totalFeesFromAmountBaseUnit.toString(),\n fromTokenAddress,\n estFeesUsd: totalFeesUsd,\n estSubtotalUsd,\n estTotalUsd,\n estCheckoutTimeMs:\n (relayQuote.details?.timeEstimate || 0) * 1000 +\n RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,\n estMarketMakerGasUsd: relayGasFeesUsd,\n lpFeePercentage: 0, // TODO: ?\n lpFeeUsd: totalLpFeesUsd,\n metadata: {\n relayQuote,\n toAmountBaseUnit: toAmountBaseUnitBIString,\n },\n }\n } catch (err) {\n throw new Error(\n `An error occured trying to generate a relay quote: ${\n err instanceof Error ? err.message : JSON.stringify(err)\n }`,\n )\n }\n}\n", "import type { Address } from 'viem'\nimport type { RelayExecutionStatus } from './types'\n\n/**\n * Fake address for a chain's native currency used by Funkit\n */\nexport const FUNKIT_NATIVE_TOKEN =\n '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' satisfies Address\n\n/**\n * Fake address for a chain's native currency used by Relay\n */\nexport const RELAY_NATIVE_TOKEN =\n '0x0000000000000000000000000000000000000000' satisfies Address\n\n/**\n * Wallet that receives the app fees collected by Relay\n */\nexport const FUN_RELAY_REVENUE_WALLET =\n '0xb61562d83aEC43a050A06BED12Ac2bD8f9BFfd5E' satisfies Address\n\n/**\n * Referred field in Relay quote\n */\nexport const FUN_RELAY_REFERRER = 'funxyz'\n\n/**\n * Buffer added to Relay's time estimate (which sometimes is 0)\n */\nexport const RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 3_000 // 3 seconds\n\nexport const RELAY_TERMINAL_STATUSES: RelayExecutionStatus[] = [\n 'refund',\n 'failure',\n 'success',\n]\n", "import type { CallFees } from '@reservoir0x/relay-sdk'\nimport type { Logger } from './types'\n\nexport function computeFunRelayFeeBps({\n isSameToken,\n}: {\n isSameToken: boolean\n}): number {\n // For now, we have a flat 2bps app fee for all relay transactions\n // TODO: Dynamic fee based on the transaction size, from token, to token, etc\n return isSameToken ? 0 : 2\n}\n\nexport function parseRelayFees({\n fees,\n logger,\n}: {\n fees: CallFees | undefined\n logger: Logger\n}) {\n // Gas fees, denominated in source chain native token\n const relayGasFeesUsd = Number.parseFloat(fees?.gas?.amountUsd || '0')\n\n // App fees, denominated in source chain token\n const funLpFeesUsd = Number.parseFloat(fees?.app?.amountUsd || '0')\n const funLpFeesFromAmount = Number.parseFloat(\n fees?.app?.amountFormatted || '0',\n )\n const funLpFeesFromAmountBaseUnit = BigInt(fees?.app?.amount || '0')\n\n // Relay fees, denominated in source chain token\n const relayLpFeesUsd =\n Number.parseFloat(fees?.relayer?.amountUsd || '0') +\n Number.parseFloat(fees?.relayerGas?.amountUsd || '0') +\n Number.parseFloat(fees?.relayerService?.amountUsd || '0')\n const relayLpFeesFromAmount =\n Number.parseFloat(fees?.relayer?.amountFormatted || '0') +\n Number.parseFloat(fees?.relayerGas?.amountFormatted || '0') +\n Number.parseFloat(fees?.relayerService?.amountFormatted || '0')\n const relayLpFeesFromAmountBaseUnit =\n BigInt(fees?.relayer?.amount || '0') +\n BigInt(fees?.relayerGas?.amount || '0') +\n BigInt(fees?.relayerService?.amount || '0')\n\n const totalLpFeesUsd = funLpFeesUsd + relayLpFeesUsd\n const totalLpFeesFromAmount = funLpFeesFromAmount + relayLpFeesFromAmount\n const totalLpFeesFromAmountBaseUnit =\n funLpFeesFromAmountBaseUnit + relayLpFeesFromAmountBaseUnit\n\n logger.log('parseRelayFees', {\n relayGasFeesUsd,\n funLpFeesUsd,\n funLpFeesFromAmount,\n funLpFeesFromAmountBaseUnit,\n relayLpFeesUsd,\n relayLpFeesFromAmount,\n relayLpFeesFromAmountBaseUnit,\n totalLpFeesUsd,\n totalLpFeesFromAmount,\n totalLpFeesFromAmountBaseUnit,\n })\n\n return {\n relayGasFeesUsd,\n totalLpFeesUsd,\n totalFeesUsd: relayGasFeesUsd + totalLpFeesUsd,\n totalFeesFromAmount: totalLpFeesFromAmount,\n totalFeesFromAmountBaseUnit: totalLpFeesFromAmountBaseUnit,\n }\n}\n", "import { LogLevel } from '@reservoir0x/relay-sdk'\nimport type { Abi, Address } from 'viem'\n\nexport { LogLevel }\n\nexport type RelayExecutionStatus =\n | 'refund'\n | 'delayed'\n | 'waiting'\n | 'failure'\n | 'pending'\n | 'success'\n\n// https://docs.relay.link/references/api/get-intents-status-v2\nexport interface RelayExecutionInfo {\n status: RelayExecutionStatus\n details: string\n /** Incoming transaction hashes */\n inTxHashes: string[]\n /** Outgoing transaction hashes */\n txHashes: string[]\n /** The last timestamp the data was updated in milliseconds */\n time: number\n originChainId: number\n destinationChainId: number\n}\n\n//// The types below are duplicated from @funkit/api-base atm, but this package should be used in BE as well\n//// TODO: Are we fine with BE importing @funkit/api-base and (by extension) @funkit/utils?\n//// See https://linear.app/funxyz/issue/PE-1342/sdk-extract-domainsrelayts-to-a-new-package#comment-d487d533\n\nexport interface Logger {\n error(message: string, data?: object): void\n log(message: string, data?: object): void\n}\n\nexport interface ApiFunkitCheckoutActionParams {\n contractAbi: Abi\n contractAddress: Address\n functionName: string\n functionArgs: unknown[]\n value?: bigint\n}\n\nexport enum CheckoutRefundState {\n INITIATED = 'INITIATED',\n ERROR = 'ERROR',\n REFUNDED = 'REFUNDED',\n PROCEEDED = 'PROCEEDED',\n WAITING_FOR_FULFILLMENT = 'WAITING_FOR_FULFILLMENT',\n FULFILLED = 'FULFILLED',\n}\n\n// Reference from api server: https://github.com/fun-xyz/fun-api-server/blob/main/src/tables/FunWalletCheckout.ts#L11C1-L21C2\nexport enum CheckoutState {\n // In-progress States\n FROM_UNFUNDED = 'FROM_UNFUNDED',\n FROM_FUNDED = 'FROM_FUNDED',\n FROM_POOLED = 'FROM_POOLED',\n TO_UNFUNDED = 'TO_UNFUNDED',\n TO_FUNDED = 'TO_FUNDED',\n TO_POOLED = 'TO_POOLED',\n TO_READY = 'TO_READY',\n PENDING_RECEIVAL = 'PENDING_RECEIVAL',\n // Terminal States\n COMPLETED = 'COMPLETED',\n CHECKOUT_ERROR = 'CHECKOUT_ERROR',\n EXPIRED = 'EXPIRED',\n CANCELLED = 'CANCELLED',\n}\n\n// The response of the actual /checkout/quote api\nexport type CheckoutApiQuoteResponse = {\n quoteId: string\n estTotalFromAmountBaseUnit: string\n estSubtotalFromAmountBaseUnit: string\n estFeesFromAmountBaseUnit: string\n fromTokenAddress: Address\n estFeesUsd: number\n estSubtotalUsd: number\n estTotalUsd: number\n estCheckoutTimeMs: number\n estMarketMakerGasUsd: number\n lpFeePercentage: number\n lpFeeUsd: number\n}\n\n// The formatted response quote interface from the core sdk\nexport type CheckoutQuoteResponse = CheckoutApiQuoteResponse & {\n estTotalFromAmount: string\n estSubtotalFromAmount: string\n estFeesFromAmount: string\n\n // Any additional fields purely for frontend use\n metadata?: { [key: string]: unknown }\n}\n", "import type { Address } from 'viem'\nimport {\n FUNKIT_NATIVE_TOKEN,\n RELAY_NATIVE_TOKEN,\n RELAY_TERMINAL_STATUSES,\n} from './constants'\nimport {\n CheckoutRefundState,\n CheckoutState,\n type RelayExecutionInfo,\n} from './types'\n\n/**\n * Converts a token address within Funkit the corresponding Relay token address.\n */\nexport function convertFunToRelayTokenAddress(address: Address): Address {\n if (address.toLowerCase() === FUNKIT_NATIVE_TOKEN.toLowerCase()) {\n return RELAY_NATIVE_TOKEN\n }\n\n return address\n}\n\nexport function getRelayExecutionRefundState(\n info: RelayExecutionInfo,\n): CheckoutRefundState | undefined {\n switch (info.status) {\n case 'refund':\n return CheckoutRefundState.REFUNDED\n default:\n return undefined\n }\n}\n\nexport function getRelayExecutionState(\n info: RelayExecutionInfo,\n): CheckoutState {\n switch (info.status) {\n case 'success':\n return CheckoutState.COMPLETED\n case 'failure':\n case 'refund':\n return CheckoutState.CHECKOUT_ERROR\n default:\n return CheckoutState.PENDING_RECEIVAL\n }\n}\n\n/**\n * Checks whether the Relay execution has reached a terminal status.\n */\nexport function isRelayExecutionTerminalStatus(\n info: RelayExecutionInfo,\n): boolean {\n return RELAY_TERMINAL_STATUSES.includes(info.status)\n}\n"],
5
- "mappings": "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",
6
- "names": ["MAINNET_RELAY_API", "MAINNET_RELAY_API"]
3
+ "sources": ["../src/client.ts", "../src/types.ts", "../src/constants.ts", "../src/execution.ts", "../src/fees.ts", "../src/price.ts", "../src/quote.ts", "../src/utils.ts"],
4
+ "sourcesContent": ["import {\n MAINNET_RELAY_API,\n type RelayClient,\n type RelayClientOptions,\n convertViemChainToRelayChain,\n createClient,\n getClient,\n} from '@reservoir0x/relay-sdk'\nimport type { Chain } from 'viem'\nimport type { Logger } from './types'\n\nexport type InitializeRelayClientParams = Omit<\n RelayClientOptions,\n 'baseApiUrl' | 'chains' | 'logger'\n> & {\n chains: Chain[]\n logger: Logger\n}\n\n/**\n * Initializes a global instance of the RelayClient\n * https://docs.relay.link/references/sdk/createClient\n */\nexport function initializeRelayClient({\n chains,\n logger,\n ...options\n}: InitializeRelayClientParams): RelayClient {\n return createClient({\n ...options,\n baseApiUrl: MAINNET_RELAY_API,\n chains: chains.map(convertViemChainToRelayChain),\n logger: (message) => {\n logger.info('[RelayClient]:', message)\n },\n })\n}\n\n/**\n * Gets the global instance of the RelayClient\n */\nexport function getRelayClient(): RelayClient {\n const client = getClient()\n\n if (!client) {\n throw new Error('Relay client is not defined')\n }\n\n return client\n}\n", "import { LogLevel } from '@reservoir0x/relay-sdk'\nimport type { Abi, Address } from 'viem'\n\nexport { LogLevel }\n\n// https://docs.relay.link/references/api/get-intents-status-v2\nexport interface RelayExecutionInfo {\n status: RelayExecutionStatus\n details: string\n /** Incoming transaction hashes */\n inTxHashes: string[]\n /** Outgoing transaction hashes */\n txHashes: string[]\n /** The last timestamp the data was updated in milliseconds */\n time: number\n originChainId: number\n destinationChainId: number\n}\n\n// https://docs.relay.link/references/api/get-token-price\nexport interface RelayTokenPriceInfo {\n price: number\n}\n\n//// The types below are duplicated from @funkit/api-base atm, but this package should be used in BE as well\n//// TODO: Are we fine with BE importing @funkit/api-base and (by extension) @funkit/utils?\n//// See https://linear.app/funxyz/issue/PE-1342/sdk-extract-domainsrelayts-to-a-new-package#comment-d487d533\n\nexport interface Logger {\n error(message: string, data?: object): void\n info(message: string, data?: object): void\n}\n\n// Reference: https://github.com/reservoirprotocol/relay-kit/blob/211c645f9702a3b459ff545aa4e2e9d536c38455/packages/sdk/src/types/Execute.ts#L54-L61\nexport enum RelayExecutionStatus {\n DELAYED = 'delayed',\n FAILURE = 'failure',\n PENDING = 'pending',\n REFUND = 'refund',\n SUCCESS = 'success',\n WAITING = 'waiting',\n UNKNOWN = 'unknown',\n}\n\nexport interface ApiFunkitCheckoutActionParams {\n contractAbi: Abi\n contractAddress: Address\n functionName: string\n functionArgs: unknown[]\n value?: bigint\n}\n\nexport enum CheckoutRefundState {\n INITIATED = 'INITIATED',\n ERROR = 'ERROR',\n REFUNDED = 'REFUNDED',\n PROCEEDED = 'PROCEEDED',\n WAITING_FOR_FULFILLMENT = 'WAITING_FOR_FULFILLMENT',\n FULFILLED = 'FULFILLED',\n}\n\n// Reference from api server: https://github.com/fun-xyz/fun-api-server/blob/main/src/tables/FunWalletCheckout.ts#L11C1-L21C2\nexport enum CheckoutState {\n // In-progress States\n FROM_UNFUNDED = 'FROM_UNFUNDED',\n FROM_FUNDED = 'FROM_FUNDED',\n FROM_POOLED = 'FROM_POOLED',\n TO_UNFUNDED = 'TO_UNFUNDED',\n TO_FUNDED = 'TO_FUNDED',\n TO_POOLED = 'TO_POOLED',\n TO_READY = 'TO_READY',\n PENDING_RECEIVAL = 'PENDING_RECEIVAL',\n // Terminal States\n COMPLETED = 'COMPLETED',\n CHECKOUT_ERROR = 'CHECKOUT_ERROR',\n EXPIRED = 'EXPIRED',\n CANCELLED = 'CANCELLED',\n}\n\n// The response of the actual /checkout/quote api\nexport type CheckoutApiQuoteResponse = {\n quoteId: string\n estTotalFromAmountBaseUnit: string\n estSubtotalFromAmountBaseUnit: string\n estFeesFromAmountBaseUnit: string\n fromTokenAddress: Address\n estFeesUsd: number\n estSubtotalUsd: number\n estTotalUsd: number\n estCheckoutTimeMs: number\n estMarketMakerGasUsd: number\n lpFeePercentage: number\n lpFeeUsd: number\n}\n\n// The formatted response quote interface from the core sdk\nexport type CheckoutQuoteResponse = CheckoutApiQuoteResponse & {\n estTotalFromAmount: string\n estSubtotalFromAmount: string\n estFeesFromAmount: string\n\n // Any additional fields purely for frontend use\n metadata?: { [key: string]: unknown }\n}\n", "import type { Address } from 'viem'\nimport { RelayExecutionStatus } from './types'\n\n/**\n * Fake address for a chain's native currency used by Funkit\n */\nexport const FUNKIT_NATIVE_TOKEN =\n '0xeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeeee' satisfies Address\n\n/**\n * Fake address for a chain's native currency used by Relay\n */\nexport const RELAY_NATIVE_TOKEN =\n '0x0000000000000000000000000000000000000000' satisfies Address\n\n/**\n * Wallet that receives the app fees collected by Relay\n */\nexport const FUN_RELAY_REVENUE_WALLET =\n '0xb61562d83aEC43a050A06BED12Ac2bD8f9BFfd5E' satisfies Address\n\n/**\n * Referred field in Relay quote\n */\nexport const FUN_RELAY_REFERRER = 'funxyz'\n\n/**\n * Buffer added to Relay's time estimate (which sometimes is 0)\n */\nexport const RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS = 3_000 // 3 seconds\n\nexport const RELAY_TERMINAL_STATUSES: RelayExecutionStatus[] = [\n RelayExecutionStatus.REFUND,\n RelayExecutionStatus.FAILURE,\n RelayExecutionStatus.SUCCESS,\n]\n", "import {\n type Execute,\n MAINNET_RELAY_API,\n type ProgressData,\n} from '@reservoir0x/relay-sdk'\nimport type { Hex, WalletClient } from 'viem'\nimport { getRelayClient } from './client'\nimport type { Logger, RelayExecutionInfo } from './types'\n\nexport type RelayExecutionStep = ProgressData['currentStep'] & {}\n\nexport interface ExecuteRelayQuoteParams {\n logger: Logger\n onConfirmed: (txHash: Hex) => Promise<void>\n onError: (error: Error) => Promise<void>\n onProgress?: (step: RelayExecutionStep | null) => void\n relayQuote: Execute\n walletClient: WalletClient\n}\n\nexport async function executeRelayQuote({\n logger,\n onConfirmed,\n onError,\n onProgress,\n relayQuote,\n walletClient,\n}: ExecuteRelayQuoteParams) {\n await getRelayClient().actions.execute({\n quote: relayQuote,\n wallet: walletClient,\n onProgress: async ({\n steps,\n fees,\n breakdown,\n currentStep,\n currentStepItem,\n txHashes,\n details,\n error,\n }) => {\n const logPrefix = 'onRelayProgress'\n logger.info(`${logPrefix}:params`, {\n steps,\n currentStep,\n fees,\n breakdown,\n currentStepItem,\n txHashes,\n details,\n error,\n })\n\n onProgress?.(currentStep ?? null)\n\n if (error) {\n logger.info(`${logPrefix}:errorDetected`, error)\n await onError(error).catch((e) => {\n logger.error(`${logPrefix}:onErrorFailed`, e)\n })\n } else if (\n // We can redirect as soon as all the required user steps are done\n // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1748381169792379\n txHashes &&\n txHashes.length > 0 &&\n txHashes.length === steps.length\n ) {\n logger.info(`${logPrefix}:completed`, txHashes)\n // Can we assume its completed here?\n // Use first txHash as the main txHash in fun DE table\n await onConfirmed(txHashes[0].txHash as Hex).catch((e) => {\n logger.error(`${logPrefix}:onConfirmedFailed`, e)\n })\n }\n },\n })\n}\n\nexport async function getRelayExecutionInfo(\n requestId: string,\n): Promise<RelayExecutionInfo> {\n const url = `${MAINNET_RELAY_API}/intents/status/v2?requestId=${requestId}`\n const response = await fetch(url)\n if (!response.ok) {\n throw Error(response.statusText)\n }\n\n const data = await response.json()\n return data as RelayExecutionInfo\n}\n", "import type { CallFees } from '@reservoir0x/relay-sdk'\nimport type { Logger } from './types'\n\nexport function computeFunRelayFeeBps({\n isSameToken,\n}: {\n isSameToken: boolean\n}): number {\n // For now, we have a flat 2bps app fee for all relay transactions\n // TODO: Dynamic fee based on the transaction size, from token, to token, etc\n return isSameToken ? 0 : 2\n}\n\nexport function parseRelayFees({\n fees,\n logger,\n}: {\n fees: CallFees | undefined\n logger: Logger\n}) {\n // Gas fees, denominated in source chain native token\n const relayGasFeesUsd = Number.parseFloat(fees?.gas?.amountUsd || '0')\n\n // App fees, denominated in source chain token\n const funLpFeesUsd = Number.parseFloat(fees?.app?.amountUsd || '0')\n const funLpFeesFromAmount = Number.parseFloat(\n fees?.app?.amountFormatted || '0',\n )\n const funLpFeesFromAmountBaseUnit = BigInt(fees?.app?.amount || '0')\n\n // Relay fees, denominated in source chain token\n const relayLpFeesUsd =\n Number.parseFloat(fees?.relayer?.amountUsd || '0') +\n Number.parseFloat(fees?.relayerGas?.amountUsd || '0') +\n Number.parseFloat(fees?.relayerService?.amountUsd || '0')\n const relayLpFeesFromAmount =\n Number.parseFloat(fees?.relayer?.amountFormatted || '0') +\n Number.parseFloat(fees?.relayerGas?.amountFormatted || '0') +\n Number.parseFloat(fees?.relayerService?.amountFormatted || '0')\n const relayLpFeesFromAmountBaseUnit =\n BigInt(fees?.relayer?.amount || '0') +\n BigInt(fees?.relayerGas?.amount || '0') +\n BigInt(fees?.relayerService?.amount || '0')\n\n const totalLpFeesUsd = funLpFeesUsd + relayLpFeesUsd\n const totalLpFeesFromAmount = funLpFeesFromAmount + relayLpFeesFromAmount\n const totalLpFeesFromAmountBaseUnit =\n funLpFeesFromAmountBaseUnit + relayLpFeesFromAmountBaseUnit\n\n logger.info('parseRelayFees', {\n relayGasFeesUsd,\n funLpFeesUsd,\n funLpFeesFromAmount,\n funLpFeesFromAmountBaseUnit,\n relayLpFeesUsd,\n relayLpFeesFromAmount,\n relayLpFeesFromAmountBaseUnit,\n totalLpFeesUsd,\n totalLpFeesFromAmount,\n totalLpFeesFromAmountBaseUnit,\n })\n\n return {\n relayGasFeesUsd,\n totalLpFeesUsd,\n totalFeesUsd: relayGasFeesUsd + totalLpFeesUsd,\n totalFeesFromAmount: totalLpFeesFromAmount,\n totalFeesFromAmountBaseUnit: totalLpFeesFromAmountBaseUnit,\n }\n}\n", "import { MAINNET_RELAY_API } from '@reservoir0x/relay-sdk'\nimport type { RelayTokenPriceInfo } from './types'\n\nexport async function getRelayAssetPriceInfo({\n chainId,\n address,\n}: {\n chainId: string\n address: string\n}): Promise<RelayTokenPriceInfo> {\n const url = `${MAINNET_RELAY_API}/currencies/token/price?chainId=${chainId}&address=${address}`\n const response = await fetch(url)\n if (!response.ok) {\n throw Error(response.statusText)\n }\n\n const data = await response.json()\n return data as RelayTokenPriceInfo\n}\n", "import type { Execute, GetQuoteParameters } from '@reservoir0x/relay-sdk'\nimport { type Address, encodeFunctionData } from 'viem'\nimport { getRelayClient } from './client'\nimport {\n FUN_RELAY_REFERRER,\n FUN_RELAY_REVENUE_WALLET,\n RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,\n} from './constants'\nimport { computeFunRelayFeeBps, parseRelayFees } from './fees'\nimport type {\n ApiFunkitCheckoutActionParams,\n CheckoutQuoteResponse,\n Logger,\n} from './types'\nimport { convertFunToRelayTokenAddress } from './utils'\n\ntype RelayQuoteOptions = GetQuoteParameters['options'] & {}\n\nexport type GetRelayQuoteParams = {\n actionParams?: ApiFunkitCheckoutActionParams[]\n fromChainId: string\n fromTokenAddress: Address\n logger: Logger\n /**\n * {@link getRelayQuote} already sets {@link RelayQuoteOptions.appFees|appFees} and {@link RelayQuoteOptions.referrer|referrer}.\n * Only include them if you wish to override.\n */\n options?: RelayQuoteOptions\n recipientAddress: Address | undefined\n toChainId: string\n toTokenAddress: Address\n tradeType: 'EXACT_INPUT' | 'EXACT_OUTPUT'\n userAddress: Address | undefined\n} & (\n | {\n fromTokenAmountBaseUnit: bigint | string\n tradeType: 'EXACT_INPUT'\n }\n | {\n toTokenAmountBaseUnit: bigint | string\n tradeType: 'EXACT_OUTPUT'\n }\n)\n\nexport type RelayQuote = CheckoutQuoteResponse & {\n /** Required for EXACT_INPUT checkouts */\n finalToAmountBaseUnit: string\n metadata: {\n fromAmountBaseUnit: string\n relayQuote: Execute\n toAmountBaseUnit: string\n }\n}\n\nexport async function getRelayQuote({\n logger,\n ...params\n}: GetRelayQuoteParams): Promise<RelayQuote> {\n const {\n actionParams,\n fromChainId,\n fromTokenAddress,\n options,\n recipientAddress,\n toChainId,\n toTokenAddress,\n userAddress,\n } = params\n\n try {\n const relayClient = getRelayClient()\n\n const tokenAmountBaseUnit =\n params.tradeType === 'EXACT_INPUT'\n ? params.fromTokenAmountBaseUnit\n : params.toTokenAmountBaseUnit\n\n const txs = actionParams?.map((action) => {\n const data = encodeFunctionData({\n abi: action.contractAbi,\n args: action.functionArgs,\n functionName: action.functionName,\n })\n\n return {\n data,\n to: action.contractAddress,\n value: String(action.value ?? 0n),\n }\n })\n\n logger.info('getRelayQuoteParams', {\n ...params,\n tokenAmountBaseUnit,\n txs,\n })\n\n // Get the relay quote\n const relayQuote = await relayClient.actions.getQuote({\n chainId: Number(fromChainId),\n toChainId: Number(toChainId),\n currency: convertFunToRelayTokenAddress(fromTokenAddress),\n toCurrency: convertFunToRelayTokenAddress(toTokenAddress),\n amount: tokenAmountBaseUnit.toString(),\n recipient: recipientAddress,\n tradeType: params.tradeType,\n user: userAddress,\n ...(txs && { txs }),\n options: {\n referrer: FUN_RELAY_REFERRER,\n appFees: [\n {\n fee: computeFunRelayFeeBps({\n isSameToken:\n fromChainId === toChainId &&\n fromTokenAddress.toLowerCase() === toTokenAddress.toLowerCase(),\n }).toString(),\n recipient: FUN_RELAY_REVENUE_WALLET,\n },\n ],\n ...options,\n },\n })\n\n // TODO: Handling for no route response\n\n logger.info('relayQuote', relayQuote)\n\n const estSubtotalUsd = Number(\n relayQuote.details?.currencyOut?.amountUsd || 0,\n )\n const estTotalUsd = Number(relayQuote.details?.currencyIn?.amountUsd || 0)\n // Get how much fromAmount is needed for the quote\n const fromAmountString =\n relayQuote.details?.currencyIn?.amountFormatted || '0'\n const fromAmountBaseUnitString =\n relayQuote.details?.currencyIn?.amount || '0'\n\n // RequestID will be consistent across steps in the quote\n // https://fun-xyz.slack.com/archives/C08MQ85QB2N/p1747774944603209\n const relayRequestId = relayQuote.steps[0]?.requestId\n\n // TODO: Verify with relay team if this is possible?\n if (!relayRequestId) {\n throw new Error('Relay quote does not contain a requestId')\n }\n\n // TODO: Verify with relay team if this is possible?\n if (!relayQuote.details?.currencyIn || !relayQuote.details?.currencyOut) {\n throw new Error('Relay quote does not contain trade details')\n }\n\n const {\n relayGasFeesUsd,\n totalLpFeesUsd,\n totalFeesUsd,\n totalFeesFromAmount,\n totalFeesFromAmountBaseUnit,\n } = parseRelayFees({ fees: relayQuote.fees, logger })\n\n const estSubtotalFromAmount = (\n Number.parseFloat(fromAmountString) - totalFeesFromAmount\n ).toString()\n\n const estSubtotalFromAmountBaseUnit = (\n BigInt(fromAmountBaseUnitString) - totalFeesFromAmountBaseUnit\n ).toString()\n\n return {\n quoteId: relayRequestId,\n estCheckoutTimeMs:\n (relayQuote.details.timeEstimate || 0) * 1000 +\n RELAY_QUOTE_CHECKOUT_TIME_BUFFER_MS,\n estFeesFromAmount: totalFeesFromAmount.toString(),\n estFeesFromAmountBaseUnit: totalFeesFromAmountBaseUnit.toString(),\n estFeesUsd: totalFeesUsd,\n estMarketMakerGasUsd: relayGasFeesUsd,\n estSubtotalFromAmount,\n estSubtotalFromAmountBaseUnit,\n estSubtotalUsd,\n estTotalFromAmount: fromAmountString,\n estTotalFromAmountBaseUnit: fromAmountBaseUnitString,\n estTotalUsd,\n finalToAmountBaseUnit: relayQuote.details.currencyOut.amount ?? '0', // TODO: Or do we want 'minimumAmount'?\n fromTokenAddress,\n lpFeePercentage: 0, // TODO: ?\n lpFeeUsd: totalLpFeesUsd,\n metadata: {\n fromAmountBaseUnit:\n params.tradeType === 'EXACT_INPUT'\n ? tokenAmountBaseUnit.toString()\n : (relayQuote.details.currencyIn.amount ?? '0'),\n relayQuote,\n toAmountBaseUnit:\n params.tradeType === 'EXACT_INPUT'\n ? (relayQuote.details.currencyOut.amount ?? '0')\n : tokenAmountBaseUnit.toString(),\n },\n }\n } catch (err) {\n throw new Error(\n `An error occurred trying to generate a relay quote: ${\n err instanceof Error ? err.message : JSON.stringify(err)\n }`,\n )\n }\n}\n", "import type { Address } from 'viem'\nimport {\n FUNKIT_NATIVE_TOKEN,\n RELAY_NATIVE_TOKEN,\n RELAY_TERMINAL_STATUSES,\n} from './constants'\nimport {\n CheckoutRefundState,\n CheckoutState,\n type RelayExecutionInfo,\n} from './types'\n\n/**\n * Converts a token address within Funkit the corresponding Relay token address.\n */\nexport function convertFunToRelayTokenAddress(address: Address): Address {\n if (address.toLowerCase() === FUNKIT_NATIVE_TOKEN.toLowerCase()) {\n return RELAY_NATIVE_TOKEN\n }\n\n return address\n}\n\nexport function getRelayExecutionRefundState(\n info: RelayExecutionInfo,\n): CheckoutRefundState | undefined {\n switch (info.status) {\n case 'refund':\n return CheckoutRefundState.REFUNDED\n default:\n return undefined\n }\n}\n\nexport function getRelayExecutionState(\n info: RelayExecutionInfo,\n): CheckoutState {\n switch (info.status) {\n case 'success':\n return CheckoutState.COMPLETED\n case 'failure':\n case 'refund':\n return CheckoutState.CHECKOUT_ERROR\n default:\n return CheckoutState.PENDING_RECEIVAL\n }\n}\n\n/**\n * Checks whether the Relay execution has reached a terminal status.\n */\nexport function isRelayExecutionTerminalStatus(\n info: RelayExecutionInfo,\n): boolean {\n return RELAY_TERMINAL_STATUSES.includes(info.status)\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["MAINNET_RELAY_API", "MAINNET_RELAY_API", "MAINNET_RELAY_API"]
7
7
  }
@@ -1,4 +1,4 @@
1
- import type { RelayExecutionStatus } from './types';
1
+ import { RelayExecutionStatus } from './types';
2
2
  /**
3
3
  * Fake address for a chain's native currency used by Funkit
4
4
  */
@@ -1 +1 @@
1
- {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAEnD;;GAEG;AACH,eAAO,MAAM,mBAAmB,+CACgC,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,kBAAkB,+CACiC,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,wBAAwB,+CAC2B,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,kBAAkB,WAAW,CAAA;AAE1C;;GAEG;AACH,eAAO,MAAM,mCAAmC,OAAQ,CAAA;AAExD,eAAO,MAAM,uBAAuB,EAAE,oBAAoB,EAIzD,CAAA"}
1
+ {"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../../src/constants.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,oBAAoB,EAAE,MAAM,SAAS,CAAA;AAE9C;;GAEG;AACH,eAAO,MAAM,mBAAmB,+CACgC,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,kBAAkB,+CACiC,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,wBAAwB,+CAC2B,CAAA;AAEhE;;GAEG;AACH,eAAO,MAAM,kBAAkB,WAAW,CAAA;AAE1C;;GAEG;AACH,eAAO,MAAM,mCAAmC,OAAQ,CAAA;AAExD,eAAO,MAAM,uBAAuB,EAAE,oBAAoB,EAIzD,CAAA"}
@@ -1,14 +1,15 @@
1
- import { type Execute } from '@reservoir0x/relay-sdk';
1
+ import { type Execute, type ProgressData } from '@reservoir0x/relay-sdk';
2
2
  import type { Hex, WalletClient } from 'viem';
3
3
  import type { Logger, RelayExecutionInfo } from './types';
4
+ export type RelayExecutionStep = ProgressData['currentStep'] & {};
4
5
  export interface ExecuteRelayQuoteParams {
5
6
  logger: Logger;
6
7
  onConfirmed: (txHash: Hex) => Promise<void>;
7
8
  onError: (error: Error) => Promise<void>;
9
+ onProgress?: (step: RelayExecutionStep | null) => void;
8
10
  relayQuote: Execute;
9
- stepMessageSetter: (message: string) => void;
10
11
  walletClient: WalletClient;
11
12
  }
12
- export declare function executeRelayQuote({ logger, onConfirmed, onError, relayQuote, stepMessageSetter, walletClient, }: ExecuteRelayQuoteParams): Promise<void>;
13
+ export declare function executeRelayQuote({ logger, onConfirmed, onError, onProgress, relayQuote, walletClient, }: ExecuteRelayQuoteParams): Promise<void>;
13
14
  export declare function getRelayExecutionInfo(requestId: string): Promise<RelayExecutionInfo>;
14
15
  //# sourceMappingURL=execution.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/execution.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAqB,MAAM,wBAAwB,CAAA;AACxE,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEzD,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,UAAU,EAAE,OAAO,CAAA;IACnB,iBAAiB,EAAE,CAAC,OAAO,EAAE,MAAM,KAAK,IAAI,CAAA;IAC5C,YAAY,EAAE,YAAY,CAAA;CAC3B;AAGD,wBAAsB,iBAAiB,CAAC,EACtC,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,iBAAiB,EACjB,YAAY,GACb,EAAE,uBAAuB,iBAiDzB;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAS7B"}
1
+ {"version":3,"file":"execution.d.ts","sourceRoot":"","sources":["../../src/execution.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,OAAO,EAEZ,KAAK,YAAY,EAClB,MAAM,wBAAwB,CAAA;AAC/B,OAAO,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,MAAM,MAAM,CAAA;AAE7C,OAAO,KAAK,EAAE,MAAM,EAAE,kBAAkB,EAAE,MAAM,SAAS,CAAA;AAEzD,MAAM,MAAM,kBAAkB,GAAG,YAAY,CAAC,aAAa,CAAC,GAAG,EAAE,CAAA;AAEjE,MAAM,WAAW,uBAAuB;IACtC,MAAM,EAAE,MAAM,CAAA;IACd,WAAW,EAAE,CAAC,MAAM,EAAE,GAAG,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IAC3C,OAAO,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,OAAO,CAAC,IAAI,CAAC,CAAA;IACxC,UAAU,CAAC,EAAE,CAAC,IAAI,EAAE,kBAAkB,GAAG,IAAI,KAAK,IAAI,CAAA;IACtD,UAAU,EAAE,OAAO,CAAA;IACnB,YAAY,EAAE,YAAY,CAAA;CAC3B;AAED,wBAAsB,iBAAiB,CAAC,EACtC,MAAM,EACN,WAAW,EACX,OAAO,EACP,UAAU,EACV,UAAU,EACV,YAAY,GACb,EAAE,uBAAuB,iBAiDzB;AAED,wBAAsB,qBAAqB,CACzC,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,kBAAkB,CAAC,CAS7B"}
@@ -0,0 +1,6 @@
1
+ import type { RelayTokenPriceInfo } from './types';
2
+ export declare function getRelayAssetPriceInfo({ chainId, address, }: {
3
+ chainId: string;
4
+ address: string;
5
+ }): Promise<RelayTokenPriceInfo>;
6
+ //# sourceMappingURL=price.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"price.d.ts","sourceRoot":"","sources":["../../src/price.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,mBAAmB,EAAE,MAAM,SAAS,CAAA;AAElD,wBAAsB,sBAAsB,CAAC,EAC3C,OAAO,EACP,OAAO,GACR,EAAE;IACD,OAAO,EAAE,MAAM,CAAA;IACf,OAAO,EAAE,MAAM,CAAA;CAChB,GAAG,OAAO,CAAC,mBAAmB,CAAC,CAS/B"}
@@ -1,16 +1,38 @@
1
+ import type { Execute, GetQuoteParameters } from '@reservoir0x/relay-sdk';
1
2
  import { type Address } from 'viem';
2
3
  import type { ApiFunkitCheckoutActionParams, CheckoutQuoteResponse, Logger } from './types';
3
- export interface GetRelayQuoteParams {
4
+ type RelayQuoteOptions = GetQuoteParameters['options'] & {};
5
+ export type GetRelayQuoteParams = {
4
6
  actionParams?: ApiFunkitCheckoutActionParams[];
5
7
  fromChainId: string;
6
8
  fromTokenAddress: Address;
7
9
  logger: Logger;
10
+ /**
11
+ * {@link getRelayQuote} already sets {@link RelayQuoteOptions.appFees|appFees} and {@link RelayQuoteOptions.referrer|referrer}.
12
+ * Only include them if you wish to override.
13
+ */
14
+ options?: RelayQuoteOptions;
8
15
  recipientAddress: Address | undefined;
9
16
  toChainId: string;
10
17
  toTokenAddress: Address;
11
- toTokenAmount: number;
12
- toTokenDecimals: number;
18
+ tradeType: 'EXACT_INPUT' | 'EXACT_OUTPUT';
13
19
  userAddress: Address | undefined;
14
- }
15
- export declare function getRelayQuote({ actionParams, logger, toChainId, toTokenAddress, toTokenAmount, toTokenDecimals, fromChainId, fromTokenAddress, recipientAddress, userAddress, }: GetRelayQuoteParams): Promise<CheckoutQuoteResponse>;
20
+ } & ({
21
+ fromTokenAmountBaseUnit: bigint | string;
22
+ tradeType: 'EXACT_INPUT';
23
+ } | {
24
+ toTokenAmountBaseUnit: bigint | string;
25
+ tradeType: 'EXACT_OUTPUT';
26
+ });
27
+ export type RelayQuote = CheckoutQuoteResponse & {
28
+ /** Required for EXACT_INPUT checkouts */
29
+ finalToAmountBaseUnit: string;
30
+ metadata: {
31
+ fromAmountBaseUnit: string;
32
+ relayQuote: Execute;
33
+ toAmountBaseUnit: string;
34
+ };
35
+ };
36
+ export declare function getRelayQuote({ logger, ...params }: GetRelayQuoteParams): Promise<RelayQuote>;
37
+ export {};
16
38
  //# sourceMappingURL=quote.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../../src/quote.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,OAAO,EAAsB,MAAM,MAAM,CAAA;AAQvD,OAAO,KAAK,EACV,6BAA6B,EAC7B,qBAAqB,EACrB,MAAM,EACP,MAAM,SAAS,CAAA;AAGhB,MAAM,WAAW,mBAAmB;IAClC,YAAY,CAAC,EAAE,6BAA6B,EAAE,CAAA;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,OAAO,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,OAAO,CAAA;IACvB,aAAa,EAAE,MAAM,CAAA;IACrB,eAAe,EAAE,MAAM,CAAA;IACvB,WAAW,EAAE,OAAO,GAAG,SAAS,CAAA;CACjC;AAED,wBAAsB,aAAa,CAAC,EAClC,YAAY,EACZ,MAAM,EACN,SAAS,EACT,cAAc,EACd,aAAa,EACb,eAAe,EACf,WAAW,EACX,gBAAgB,EAChB,gBAAgB,EAChB,WAAW,GACZ,EAAE,mBAAmB,GAAG,OAAO,CAAC,qBAAqB,CAAC,CAqItD"}
1
+ {"version":3,"file":"quote.d.ts","sourceRoot":"","sources":["../../src/quote.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AACzE,OAAO,EAAE,KAAK,OAAO,EAAsB,MAAM,MAAM,CAAA;AAQvD,OAAO,KAAK,EACV,6BAA6B,EAC7B,qBAAqB,EACrB,MAAM,EACP,MAAM,SAAS,CAAA;AAGhB,KAAK,iBAAiB,GAAG,kBAAkB,CAAC,SAAS,CAAC,GAAG,EAAE,CAAA;AAE3D,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,CAAC,EAAE,6BAA6B,EAAE,CAAA;IAC9C,WAAW,EAAE,MAAM,CAAA;IACnB,gBAAgB,EAAE,OAAO,CAAA;IACzB,MAAM,EAAE,MAAM,CAAA;IACd;;;OAGG;IACH,OAAO,CAAC,EAAE,iBAAiB,CAAA;IAC3B,gBAAgB,EAAE,OAAO,GAAG,SAAS,CAAA;IACrC,SAAS,EAAE,MAAM,CAAA;IACjB,cAAc,EAAE,OAAO,CAAA;IACvB,SAAS,EAAE,aAAa,GAAG,cAAc,CAAA;IACzC,WAAW,EAAE,OAAO,GAAG,SAAS,CAAA;CACjC,GAAG,CACA;IACE,uBAAuB,EAAE,MAAM,GAAG,MAAM,CAAA;IACxC,SAAS,EAAE,aAAa,CAAA;CACzB,GACD;IACE,qBAAqB,EAAE,MAAM,GAAG,MAAM,CAAA;IACtC,SAAS,EAAE,cAAc,CAAA;CAC1B,CACJ,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,qBAAqB,GAAG;IAC/C,yCAAyC;IACzC,qBAAqB,EAAE,MAAM,CAAA;IAC7B,QAAQ,EAAE;QACR,kBAAkB,EAAE,MAAM,CAAA;QAC1B,UAAU,EAAE,OAAO,CAAA;QACnB,gBAAgB,EAAE,MAAM,CAAA;KACzB,CAAA;CACF,CAAA;AAED,wBAAsB,aAAa,CAAC,EAClC,MAAM,EACN,GAAG,MAAM,EACV,EAAE,mBAAmB,GAAG,OAAO,CAAC,UAAU,CAAC,CAqJ3C"}
@@ -1,7 +1,6 @@
1
1
  import { LogLevel } from '@reservoir0x/relay-sdk';
2
2
  import type { Abi, Address } from 'viem';
3
3
  export { LogLevel };
4
- export type RelayExecutionStatus = 'refund' | 'delayed' | 'waiting' | 'failure' | 'pending' | 'success';
5
4
  export interface RelayExecutionInfo {
6
5
  status: RelayExecutionStatus;
7
6
  details: string;
@@ -14,9 +13,21 @@ export interface RelayExecutionInfo {
14
13
  originChainId: number;
15
14
  destinationChainId: number;
16
15
  }
16
+ export interface RelayTokenPriceInfo {
17
+ price: number;
18
+ }
17
19
  export interface Logger {
18
20
  error(message: string, data?: object): void;
19
- log(message: string, data?: object): void;
21
+ info(message: string, data?: object): void;
22
+ }
23
+ export declare enum RelayExecutionStatus {
24
+ DELAYED = "delayed",
25
+ FAILURE = "failure",
26
+ PENDING = "pending",
27
+ REFUND = "refund",
28
+ SUCCESS = "success",
29
+ WAITING = "waiting",
30
+ UNKNOWN = "unknown"
20
31
  }
21
32
  export interface ApiFunkitCheckoutActionParams {
22
33
  contractAbi: Abi;
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,EAAE,QAAQ,EAAE,CAAA;AAEnB,MAAM,MAAM,oBAAoB,GAC5B,QAAQ,GACR,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,GACT,SAAS,CAAA;AAGb,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,oBAAoB,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,kCAAkC;IAClC,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAMD,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,GAAG,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC1C;AAED,MAAM,WAAW,6BAA6B;IAC5C,WAAW,EAAE,GAAG,CAAA;IAChB,eAAe,EAAE,OAAO,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,OAAO,EAAE,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,oBAAY,mBAAmB;IAC7B,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,uBAAuB,4BAA4B;IACnD,SAAS,cAAc;CACxB;AAGD,oBAAY,aAAa;IAEvB,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,gBAAgB,qBAAqB;IAErC,SAAS,cAAc;IACvB,cAAc,mBAAmB;IACjC,OAAO,YAAY;IACnB,SAAS,cAAc;CACxB;AAGD,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,0BAA0B,EAAE,MAAM,CAAA;IAClC,6BAA6B,EAAE,MAAM,CAAA;IACrC,yBAAyB,EAAE,MAAM,CAAA;IACjC,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;IACzB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAGD,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,GAAG;IAC7D,kBAAkB,EAAE,MAAM,CAAA;IAC1B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,iBAAiB,EAAE,MAAM,CAAA;IAGzB,QAAQ,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CACtC,CAAA"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/types.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAE,MAAM,wBAAwB,CAAA;AACjD,OAAO,KAAK,EAAE,GAAG,EAAE,OAAO,EAAE,MAAM,MAAM,CAAA;AAExC,OAAO,EAAE,QAAQ,EAAE,CAAA;AAGnB,MAAM,WAAW,kBAAkB;IACjC,MAAM,EAAE,oBAAoB,CAAA;IAC5B,OAAO,EAAE,MAAM,CAAA;IACf,kCAAkC;IAClC,UAAU,EAAE,MAAM,EAAE,CAAA;IACpB,kCAAkC;IAClC,QAAQ,EAAE,MAAM,EAAE,CAAA;IAClB,8DAA8D;IAC9D,IAAI,EAAE,MAAM,CAAA;IACZ,aAAa,EAAE,MAAM,CAAA;IACrB,kBAAkB,EAAE,MAAM,CAAA;CAC3B;AAGD,MAAM,WAAW,mBAAmB;IAClC,KAAK,EAAE,MAAM,CAAA;CACd;AAMD,MAAM,WAAW,MAAM;IACrB,KAAK,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;IAC3C,IAAI,CAAC,OAAO,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAC3C;AAGD,oBAAY,oBAAoB;IAC9B,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,MAAM,WAAW;IACjB,OAAO,YAAY;IACnB,OAAO,YAAY;IACnB,OAAO,YAAY;CACpB;AAED,MAAM,WAAW,6BAA6B;IAC5C,WAAW,EAAE,GAAG,CAAA;IAChB,eAAe,EAAE,OAAO,CAAA;IACxB,YAAY,EAAE,MAAM,CAAA;IACpB,YAAY,EAAE,OAAO,EAAE,CAAA;IACvB,KAAK,CAAC,EAAE,MAAM,CAAA;CACf;AAED,oBAAY,mBAAmB;IAC7B,SAAS,cAAc;IACvB,KAAK,UAAU;IACf,QAAQ,aAAa;IACrB,SAAS,cAAc;IACvB,uBAAuB,4BAA4B;IACnD,SAAS,cAAc;CACxB;AAGD,oBAAY,aAAa;IAEvB,aAAa,kBAAkB;IAC/B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,WAAW,gBAAgB;IAC3B,SAAS,cAAc;IACvB,SAAS,cAAc;IACvB,QAAQ,aAAa;IACrB,gBAAgB,qBAAqB;IAErC,SAAS,cAAc;IACvB,cAAc,mBAAmB;IACjC,OAAO,YAAY;IACnB,SAAS,cAAc;CACxB;AAGD,MAAM,MAAM,wBAAwB,GAAG;IACrC,OAAO,EAAE,MAAM,CAAA;IACf,0BAA0B,EAAE,MAAM,CAAA;IAClC,6BAA6B,EAAE,MAAM,CAAA;IACrC,yBAAyB,EAAE,MAAM,CAAA;IACjC,gBAAgB,EAAE,OAAO,CAAA;IACzB,UAAU,EAAE,MAAM,CAAA;IAClB,cAAc,EAAE,MAAM,CAAA;IACtB,WAAW,EAAE,MAAM,CAAA;IACnB,iBAAiB,EAAE,MAAM,CAAA;IACzB,oBAAoB,EAAE,MAAM,CAAA;IAC5B,eAAe,EAAE,MAAM,CAAA;IACvB,QAAQ,EAAE,MAAM,CAAA;CACjB,CAAA;AAGD,MAAM,MAAM,qBAAqB,GAAG,wBAAwB,GAAG;IAC7D,kBAAkB,EAAE,MAAM,CAAA;IAC1B,qBAAqB,EAAE,MAAM,CAAA;IAC7B,iBAAiB,EAAE,MAAM,CAAA;IAGzB,QAAQ,CAAC,EAAE;QAAE,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAA;KAAE,CAAA;CACtC,CAAA"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@funkit/fun-relay",
3
- "version": "0.1.1",
3
+ "version": "0.1.3",
4
4
  "files": [
5
5
  "dist/src",
6
6
  "dist/index.d.ts",
@@ -14,6 +14,11 @@
14
14
  "main": "./dist/index.js",
15
15
  "module": "./dist/index.mjs",
16
16
  "types": "./dist/index.d.ts",
17
+ "exports": {
18
+ "types": "./dist/index.d.ts",
19
+ "import": "./dist/index.mjs",
20
+ "require": "./dist/index.js"
21
+ },
17
22
  "sideEffects": false,
18
23
  "engines": {
19
24
  "node": ">=18"