Skip to content

Commit efaaa2b

Browse files
authored
feat: Add sweep function (#115)
closes #110
1 parent ceeac88 commit efaaa2b

File tree

12 files changed

+318
-38
lines changed

12 files changed

+318
-38
lines changed
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
---
2+
id: sweep
3+
title: sweep
4+
sidebar_position: 3
5+
---
6+
7+
# `sweep`
8+
9+
The `sweep` method generates a quote to transfer the full token balances of source chains to a destination chain.
10+
11+
## Usage
12+
13+
```typescript
14+
import { Sprinter, Environment } from "@chainsafe/sprinter-sdk";
15+
16+
const sprinter = new Sprinter({ baseUrl: Environment.TESTNET });
17+
18+
const settings = {
19+
account: "0x3E101Ec02e7A48D16DADE204C96bFF842E7E2519",
20+
destinationChain: 11155111,
21+
token: "USDC",
22+
};
23+
24+
sprinter.sweep(settings).then((solution) => {
25+
console.log(solution);
26+
});
27+
```
28+
29+
## Parameters
30+
31+
- `settings`: _(Required)_ An object containing the following fields:
32+
33+
- `account`: The user’s address.
34+
- `destinationChain`: The ID of the destination chain.
35+
- `token`: The symbol of the token to be transferred (e.g., `USDC`, `ETH`).
36+
- `recipient?`: _(Optional)_ The address of the recipient of the tokens on the destination chain.
37+
- `sourceChains?`: _(Optional)_ An array of source chain IDs to be considered for the sweep. If omitted, Sprinter will use all available chains for the solution. To limit the solution to a specific chain, provide an array containing only that chain's ID.
38+
39+
- `fetchOptions?`: _(Optional)_ An object containing `baseUrl` to override the default API endpoint for this request.
40+
41+
### Example: Using `sourceChains` for sweeping from specific chains
42+
43+
To get a sweep solution from specific chains, you can set `sourceChains` to an array with chain IDs.
44+
45+
```typescript
46+
const settings = {
47+
account: "0xYourAddressHere",
48+
destinationChain: 11155111, // Sepolia testnet
49+
token: "USDC",
50+
sourceChains: [84532, 137],
51+
};
52+
53+
sprinter.sweep(settings).then((solution) => {
54+
console.log(solution);
55+
});
56+
```
57+
58+
### Example: Using `fetchOptions`
59+
60+
```typescript
61+
sprinter.sweep(settings, { baseUrl: "https://custom.api.url" }).then((solution) => {
62+
console.log(solution);
63+
});
64+
```
65+
66+
## Response
67+
68+
Returns a promise that resolves to a `SolutionResponse`.
69+
70+
```typescript
71+
type SolutionResponse = Array<Solution> | FailedSolution;
72+
73+
interface Solution {
74+
destinationChain: number;
75+
destinationTokenAddress: string;
76+
duration: number; // Time estimate in seconds
77+
fee: Amount;
78+
gasCost: Amount;
79+
senderAddress: string;
80+
sourceChain: number;
81+
sourceTokenAddress: string;
82+
tool: Tool;
83+
transaction: Transaction;
84+
approvals?: Array<Transaction>;
85+
amount: Amount;
86+
}
87+
88+
interface FailedSolution {
89+
error: string;
90+
}
91+
```
92+
93+
### Example Response
94+
95+
import GasTip from "../\_gas-tip.md"
96+
97+
<GasTip />
98+
99+
```json
100+
[
101+
{
102+
"sourceChain": 84532,
103+
"destinationChain": 11155111,
104+
"sourceTokenAddress": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
105+
"destinationTokenAddress": "0x1c7D4B196Cb0C7B01d743Fbc6116a902379C7238",
106+
"senderAddress": "0x3E101Ec02e7A48D16DADE204C96bFF842E7E2519",
107+
"tool": {
108+
"name": "Across",
109+
"logoURI": "https://raw.githubusercontent.com/lifinance/types/main/src/assets/icons/bridges/acrossv2.png"
110+
},
111+
"gasCost": {
112+
"amount": "130680140710000",
113+
"amountUSD": 0
114+
},
115+
"fee": {
116+
"amount": "6239846",
117+
"amountUSD": 0
118+
},
119+
"amount": "1178950000",
120+
"duration": 120000000000,
121+
"transaction": {
122+
"data": "0x7b9392320000000000000000000000003e101ec02e7a48d16dade204c96bff842e7e25190000000000000000000000003e101ec02e7a48d16dade204c96bff842e7e2519000000000000000000000000036cbd53842c5426634e7929541ec2318f3dcf7e0000000000000000000000001c7d4b196cb0c7b01d743fbc6116a902379c723800000000000000000000000000000000000000000000000000000000464559700000000000000000000000000000000000000000000000000000000045e6230a0000000000000000000000000000000000000000000000000000000000aa36a70000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000006780030c000000000000000000000000000000000000000000000000000000006780576c0000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000018000000000000000000000000000000000000000000000000000000000000000001dc0de",
123+
"to": "0x82B564983aE7274c86695917BBf8C99ECb6F0F8F",
124+
"from": "0x3E101Ec02e7A48D16DADE204C96bFF842E7E2519",
125+
"value": "0x0",
126+
"gasLimit": "0x16378",
127+
"chainId": 84532
128+
},
129+
"approvals": [
130+
{
131+
"data": "0x095ea7b300000000000000000000000082b564983ae7274c86695917bbf8c99ecb6f0f8f0000000000000000000000000000000000000000000000000000000046455970",
132+
"to": "0x036CbD53842c5426634e7929541eC2318f3dCF7e",
133+
"from": "0x3E101Ec02e7A48D16DADE204C96bFF842E7E2519",
134+
"value": "0x0",
135+
"gasLimit": "0xe484",
136+
"chainId": 84532
137+
}
138+
]
139+
}
140+
]
141+
```

docs/docs/04-react-sdk/03-using-hooks.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ function YourComponent() {
2828
getUserBalances,
2929
getAvailableTokens,
3030
getAvailableChains,
31+
getSweep,
3132
getTransfer,
3233
getTransferWithHook,
3334
getPoolAssetOnDestination,

docs/docs/04-react-sdk/04-methods-reference/useSprinterTransfers.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ The `useSprinterTransfers` hook provides a simplified interface for generating c
1212
- `getTransferWithHook`: Single-hop token transfers combined with a contract call on the destination chain.
1313
- `getPoolAssetOnDestination`: Aggregates token balances across multiple chains into a single destination.
1414
- `getPoolAssetOnDestinationWithHook`: Aggregates token balances and performs a contract call on the destination chain.
15+
- `getSweep`: A function that generates a quote to transfer the full token balances of source chains to a destination chain
1516

1617
You can trigger any of these methods via the hook to fetch a cross-chain solution.
1718

@@ -59,6 +60,7 @@ The `useSprinterTransfers` hook returns an object with the following properties:
5960
- **`getTransferWithHook`**: A function that generates a single-hop token transfer combined with a contract call.
6061
- **`getPoolAssetOnDestination`**: A function that generates a solution to aggregate balances from multiple chains into a single destination.
6162
- **`getPoolAssetOnDestinationWithHook`**: A function that generates a solution to aggregate balances and execute a contract call on the destination chain.
63+
- **`getSweep`**: A function that generates a quote to transfer the full token balances of source chains to a destination chain
6264

6365
## Example Response
6466

@@ -99,5 +101,6 @@ Each method accepts a `settings` parameter, which varies depending on the operat
99101
- **`getTransferWithHook`**: See [SDK Transfer with Contract Call Method Reference](../../sdk/methods-reference/transfer/transfer-with-hook).
100102
- **`getPoolAssetOnDestination`**: See [SDK Pool Asset Method Reference](../../sdk/methods-reference/pool-asset-on-destination/pool-asset-on-destination).
101103
- **`getPoolAssetOnDestinationWithHook`**: See [SDK Pool Asset with Contract Call Method Reference](../../sdk/methods-reference/pool-asset-on-destination/pool-asset-on-destination-with-hook).
104+
- **`getSweep`**: See [Sweep Method Reference](../../sdk/methods-reference/transfer/sweep).
102105

103106
Each method calls the Sprinter SDK's corresponding function and returns the intent-based solution for cross-chain transfers or contract calls.

packages/react/lib/context.tsx

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,7 @@ export function SprinterContext({ children, baseUrl }: SprinterContextProps) {
6363
getTransferWithHook,
6464
getPoolAssetOnDestination,
6565
getPoolAssetOnDestinationWithHook,
66+
getSweep,
6667
} = useTransfers(sprinter);
6768

6869
/** Initialization */
@@ -85,6 +86,7 @@ export function SprinterContext({ children, baseUrl }: SprinterContextProps) {
8586
getTransferWithHook,
8687
getPoolAssetOnDestination,
8788
getPoolAssetOnDestinationWithHook,
89+
getSweep,
8890
}}
8991
>
9092
{children}

packages/react/lib/hooks.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ export function useSprinterBalances(account: Address) {
8383
const balances: BalancesEntry = _balances[account] || balancesEmptyState;
8484
const getUserBalances = useCallback(
8585
() => _getUserBalances(account),
86-
[_getUserBalances, account]
86+
[_getUserBalances, account],
8787
);
8888

8989
return { balances, getUserBalances };
@@ -227,6 +227,7 @@ export function useSprinterChains() {
227227
* - `getTransferWithHook`: A function to get a transfer solution that includes an additional contract call on the destination chain.
228228
* - `getPoolAssetOnDestination`: A function to get a solution for pooling assets from multiple chains and transferring them to the destination chain.
229229
* - `getPoolAssetOnDestinationWithHook`: A function to get a solution for pooling assets and performing a contract call on the destination chain.
230+
* - `getSweep`: A function to get a solution for sweeping assets from source chains to a destination chain.
230231
*
231232
* @example
232233
* ```ts
@@ -269,12 +270,14 @@ export function useSprinterTransfers() {
269270
getTransferWithHook,
270271
getPoolAssetOnDestination,
271272
getPoolAssetOnDestinationWithHook,
273+
getSweep,
272274
} = useSprinter();
273275
return {
274276
solution,
275277
getTransfer,
276278
getTransferWithHook,
277279
getPoolAssetOnDestination,
278280
getPoolAssetOnDestinationWithHook,
281+
getSweep,
279282
};
280283
}
Lines changed: 46 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,59 @@
1-
import {
2-
type SolutionResponse,
3-
Sprinter,
4-
} from "@chainsafe/sprinter-sdk";
5-
import {useCallback} from "react";
6-
import {useAsyncRequest} from "./useAsyncRequest";
7-
import type {Infer} from "superstruct";
1+
import { type SolutionResponse, Sprinter } from "@chainsafe/sprinter-sdk";
2+
import { useCallback } from "react";
3+
import { useAsyncRequest } from "./useAsyncRequest";
4+
import type { Infer } from "superstruct";
85
import {
96
MultiHopSchema,
107
MultiHopWithContractSchema,
11-
SingleHopSchema, SingleHopWithContractSchema
8+
SingleHopSchema,
9+
SingleHopWithContractSchema,
10+
SweepSchema,
1211
} from "@chainsafe/sprinter-sdk/dist/internal/validators";
1312

1413
export function useTransfers(sprinter: Sprinter) {
1514
const { state: solution, makeRequest } = useAsyncRequest<SolutionResponse>();
1615

17-
const getPoolAssetOnDestination = useCallback((settings: Infer<typeof MultiHopSchema>) => {
18-
makeRequest(sprinter.poolAssetOnDestination(settings));
19-
}, [sprinter, makeRequest]);
16+
const getPoolAssetOnDestination = useCallback(
17+
(settings: Infer<typeof MultiHopSchema>) => {
18+
makeRequest(sprinter.poolAssetOnDestination(settings));
19+
},
20+
[sprinter, makeRequest],
21+
);
22+
23+
const getPoolAssetOnDestinationWithHook = useCallback(
24+
(settings: Infer<typeof MultiHopWithContractSchema>) => {
25+
makeRequest(sprinter.poolAssetOnDestinationWithHook(settings));
26+
},
27+
[sprinter, makeRequest],
28+
);
2029

21-
const getPoolAssetOnDestinationWithHook = useCallback((settings: Infer<typeof MultiHopWithContractSchema>) => {
22-
makeRequest(sprinter.poolAssetOnDestinationWithHook(settings));
23-
}, [sprinter, makeRequest]);
30+
const getTransfer = useCallback(
31+
(settings: Infer<typeof SingleHopSchema>) => {
32+
makeRequest(sprinter.transfer(settings));
33+
},
34+
[sprinter, makeRequest],
35+
);
2436

25-
const getTransfer = useCallback((settings: Infer<typeof SingleHopSchema>) => {
26-
makeRequest(sprinter.transfer(settings));
27-
}, [sprinter, makeRequest]);
37+
const getTransferWithHook = useCallback(
38+
(settings: Infer<typeof SingleHopWithContractSchema>) => {
39+
makeRequest(sprinter.transferWithHook(settings));
40+
},
41+
[sprinter, makeRequest],
42+
);
2843

29-
const getTransferWithHook = useCallback((settings: Infer<typeof SingleHopWithContractSchema>) => {
30-
makeRequest(sprinter.transferWithHook(settings));
31-
}, [sprinter, makeRequest]);
44+
const getSweep = useCallback(
45+
(settings: Infer<typeof SweepSchema>) => {
46+
makeRequest(sprinter.sweep(settings));
47+
},
48+
[sprinter, makeRequest],
49+
);
3250

33-
return { solution, getTransfer, getTransferWithHook, getPoolAssetOnDestination, getPoolAssetOnDestinationWithHook };
51+
return {
52+
solution,
53+
getTransfer,
54+
getTransferWithHook,
55+
getPoolAssetOnDestination,
56+
getPoolAssetOnDestinationWithHook,
57+
getSweep,
58+
};
3459
}

packages/react/src/App.tsx

Lines changed: 10 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,15 @@
1-
import { useState } from 'react'
2-
import './App.css'
3-
import {SprinterContext} from "../lib/main.ts";
4-
import {Component} from "./Component.tsx";
5-
import {Action} from "./Action.tsx";
1+
import { useState } from "react";
2+
import "./App.css";
3+
import { SprinterContext } from "../lib/main.ts";
4+
import { Component } from "./Component.tsx";
5+
import { Action } from "./Action.tsx";
6+
import { Environment } from "@chainsafe/sprinter-sdk";
67

78
function App() {
8-
const [count, setCount] = useState(0)
9+
const [count, setCount] = useState(0);
910

1011
return (
11-
<SprinterContext >
12+
<SprinterContext baseUrl={Environment.TESTNET}>
1213
<div>
1314
<Component />
1415
</div>
@@ -26,7 +27,7 @@ function App() {
2627
Click on the Vite and React logos to learn more
2728
</p>
2829
</SprinterContext>
29-
)
30+
);
3031
}
3132

32-
export default App
33+
export default App;

packages/react/src/Component.tsx

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,21 @@
11
import { useEffect } from "react";
2-
import { useSprinterTokens } from "../lib/hooks.ts";
2+
import { useSprinterTokens, useSprinterTransfers } from "../lib/hooks.ts";
33

44
export function Component() {
5-
const hook = useSprinterTokens();
5+
const { getAvailableTokens } = useSprinterTokens();
6+
const { getSweep, solution } = useSprinterTransfers();
67

78
useEffect(() => {
8-
hook.getAvailableTokens();
9-
}, [hook]);
9+
getAvailableTokens();
10+
}, [getAvailableTokens]);
1011

11-
return <div>A component</div>;
12+
useEffect(() => {
13+
getSweep({
14+
account: "0x3E101Ec02e7A48D16DADE204C96bFF842E7E2519",
15+
destinationChain: 11155111,
16+
token: "USDC",
17+
});
18+
}, [getSweep]);
19+
20+
return <pre>{JSON.stringify(solution, null, 2)}</pre>;
1221
}

0 commit comments

Comments
 (0)