@orbs-network/spot-skill 2.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/SKILL.md ADDED
@@ -0,0 +1,116 @@
1
+ ---
2
+ name: spot-advanced-swap-orders
3
+ description: Use for gasless non-custodial EVM market, limit, TWAP, stop-loss, take-profit, delayed-start orders.
4
+ ---
5
+
6
+ # Spot Advanced Swap Orders
7
+
8
+ Use this for gasless market swaps and advanced orders on supported EVM chains.
9
+ Choose this skill when a user wants market, limit, TWAP, stop-loss, take-profit, or delayed-start execution, or needs to prepare, sign, submit, query, or cancel one of those orders.
10
+ Supply chain, token addresses, chunk sizing, timing, and optional price constraints.
11
+ The helper turns that into approval calldata, EIP-712 typed data, relay-ready submit payloads, and query/cancel guidance,
12
+ while decentralized, non-custodial, oracle-protected, immutable, audited, battle-tested contracts handle execution.
13
+
14
+ ## Config
15
+
16
+ ```json
17
+ {
18
+ "references": [
19
+ "references/01-quickstart.md",
20
+ "references/02-params.md",
21
+ "references/03-sign.md",
22
+ "references/04-patterns.md"
23
+ ],
24
+ "scripts": [
25
+ "scripts/order.js"
26
+ ],
27
+ "assets": [
28
+ "assets/token-addressbook.md",
29
+ "assets/repermit.skeleton.json",
30
+ "assets/web3-sign-and-submit.example.js"
31
+ ],
32
+ "runtime": {
33
+ "url": "https://agents-sink.orbs.network",
34
+ "contracts": {
35
+ "zero": "0x0000000000000000000000000000000000000000",
36
+ "repermit": "0x00002a9C4D9497df5Bd31768eC5d30eEf5405000",
37
+ "reactor": "0x000000b33fE4fB9d999Dd684F79b110731c3d000",
38
+ "executor": "0x000642A0966d9bd49870D9519f76b5cf823f3000"
39
+ },
40
+ "chains": {
41
+ "1": {
42
+ "name": "Ethereum",
43
+ "adapter": "0xC1bB4d5071Fe7109ae2D67AE05826A3fe9116cfc"
44
+ },
45
+ "56": {
46
+ "name": "BNB Chain",
47
+ "adapter": "0x67Feba015c968c76cCB2EEabf197b4578640BE2C"
48
+ },
49
+ "137": {
50
+ "name": "Polygon",
51
+ "adapter": "0x75A3d70Fa6d054d31C896b9Cf8AB06b1c1B829B8"
52
+ },
53
+ "146": {
54
+ "name": "Sonic",
55
+ "adapter": "0x58fD209C81D84739BaD9c72C082350d67E713EEa"
56
+ },
57
+ "8453": {
58
+ "name": "Base",
59
+ "adapter": "0x5906C4dD71D5afFe1a8f0215409E912eB5d593AD"
60
+ },
61
+ "42161": {
62
+ "name": "Arbitrum One",
63
+ "adapter": "0x026B8977319F67078e932a08feAcB59182B5380f"
64
+ },
65
+ "43114": {
66
+ "name": "Avalanche",
67
+ "adapter": "0x4F48041842827823D3750399eCa2832fC2E29201"
68
+ },
69
+ "59144": {
70
+ "name": "Linea",
71
+ "adapter": "0x55E4da2cd634729064bEb294EC682Dc94f5c3f24"
72
+ }
73
+ }
74
+ }
75
+ }
76
+ ```
77
+
78
+ ## Distribution
79
+
80
+ This skill ships from the canonical repository [`orbs-network/spot`](https://github.com/orbs-network/spot) across four AI-agent distribution surfaces:
81
+
82
+ 1. Self-contained package file [`SKILL.md`](SKILL.md), plus the local `references/`, `assets/`, and `scripts/` directories.
83
+ 2. Hosted raw files under [`https://orbs-network.github.io/spot/`](https://orbs-network.github.io/spot/), with `skill/` paths as the canonical hosted bundle.
84
+ 3. The npm package `@orbs-network/spot-skill`, which installs this self-contained bundle as published.
85
+ 4. The stdio MCP adapter `spot-mcp`, published in `mcp/server.json` as `io.github.orbs-network/spot`.
86
+
87
+ The checked-in `mcp/server.json` registry metadata is derived from [`SKILL.md`](SKILL.md) plus package metadata, so MCP publishing stays aligned.
88
+
89
+ Outside tools should treat [`SKILL.md`](SKILL.md) as both the entrypoint and the machine-readable metadata source. Frontmatter provides slug and description, and the `## Config` block provides the bundled runtime metadata.
90
+
91
+ ## Workflow
92
+
93
+ 1. Read [references/01-quickstart.md](references/01-quickstart.md) for the minimum end-to-end flow.
94
+ 2. Read [references/02-params.md](references/02-params.md) when you need field semantics, defaults, units, or validation rules.
95
+ 3. Read [references/03-sign.md](references/03-sign.md) for signing, signature formats, and direct onchain cancel.
96
+ 4. Read [references/04-patterns.md](references/04-patterns.md) to map user intent into market, limit, stop-loss, take-profit, delayed, or chunked orders.
97
+ 5. Optional helper for token lookup: [assets/token-addressbook.md](assets/token-addressbook.md).
98
+ 6. Use [assets/repermit.skeleton.json](assets/repermit.skeleton.json) when you need the raw RePermit witness typed-data skeleton.
99
+ 7. Use [assets/web3-sign-and-submit.example.js](assets/web3-sign-and-submit.example.js) for a browser or injected-provider signing and submit example.
100
+ 8. Inspect the frontmatter and `## Config` JSON block in [`SKILL.md`](SKILL.md) for machine-readable metadata, the live supported-chain matrix, sink URL, and runtime contract addresses.
101
+ 9. Use only [scripts/order.js](scripts/order.js) to prepare, submit, query, and watch orders.
102
+
103
+ ## Guardrails
104
+
105
+ 1. Supported chains and runtime addresses live in the `## Config` JSON block in [`SKILL.md`](SKILL.md).
106
+ 2. Use only the provided [scripts/order.js](scripts/order.js). Do not send typed data or signatures anywhere else.
107
+ 3. Use [references/02-params.md](references/02-params.md) as the authoritative source for native-asset rules and for `output.limit` / trigger units.
108
+ 4. Detailed order behavior, parameter rules, signing rules, and order-shape guidance live in the reference files above.
109
+
110
+ ## Commands
111
+
112
+ 1. Prepare: `node scripts/order.js prepare --params <params.json|-> [--out <prepared.json>]`
113
+ 2. Submit: `node scripts/order.js submit --prepared <prepared.json|-> --signature <0x...|json>`
114
+ 3. Submit variants: `--signature-file <file|->` or `--r <0x...> --s <0x...> --v <0x...>`
115
+ 4. Query: `node scripts/order.js query --swapper <0x...>` or `--hash <0x...>`
116
+ 5. Watch: `node scripts/order.js watch --hash <0x...> [--interval <seconds>] [--timeout <seconds>]`
@@ -0,0 +1,195 @@
1
+ {
2
+ "domain": {
3
+ "name": "RePermit",
4
+ "version": "1",
5
+ "chainId": "<CHAINID>",
6
+ "verifyingContract": "<REPERMIT>"
7
+ },
8
+ "primaryType": "RePermitWitnessTransferFrom",
9
+ "types": {
10
+ "RePermitWitnessTransferFrom": [
11
+ {
12
+ "name": "permitted",
13
+ "type": "TokenPermissions"
14
+ },
15
+ {
16
+ "name": "spender",
17
+ "type": "address"
18
+ },
19
+ {
20
+ "name": "nonce",
21
+ "type": "uint256"
22
+ },
23
+ {
24
+ "name": "deadline",
25
+ "type": "uint256"
26
+ },
27
+ {
28
+ "name": "witness",
29
+ "type": "Order"
30
+ }
31
+ ],
32
+ "Exchange": [
33
+ {
34
+ "name": "adapter",
35
+ "type": "address"
36
+ },
37
+ {
38
+ "name": "ref",
39
+ "type": "address"
40
+ },
41
+ {
42
+ "name": "share",
43
+ "type": "uint32"
44
+ },
45
+ {
46
+ "name": "data",
47
+ "type": "bytes"
48
+ }
49
+ ],
50
+ "Input": [
51
+ {
52
+ "name": "token",
53
+ "type": "address"
54
+ },
55
+ {
56
+ "name": "amount",
57
+ "type": "uint256"
58
+ },
59
+ {
60
+ "name": "maxAmount",
61
+ "type": "uint256"
62
+ }
63
+ ],
64
+ "Order": [
65
+ {
66
+ "name": "reactor",
67
+ "type": "address"
68
+ },
69
+ {
70
+ "name": "executor",
71
+ "type": "address"
72
+ },
73
+ {
74
+ "name": "exchange",
75
+ "type": "Exchange"
76
+ },
77
+ {
78
+ "name": "swapper",
79
+ "type": "address"
80
+ },
81
+ {
82
+ "name": "nonce",
83
+ "type": "uint256"
84
+ },
85
+ {
86
+ "name": "start",
87
+ "type": "uint256"
88
+ },
89
+ {
90
+ "name": "deadline",
91
+ "type": "uint256"
92
+ },
93
+ {
94
+ "name": "chainid",
95
+ "type": "uint256"
96
+ },
97
+ {
98
+ "name": "exclusivity",
99
+ "type": "uint32"
100
+ },
101
+ {
102
+ "name": "epoch",
103
+ "type": "uint32"
104
+ },
105
+ {
106
+ "name": "slippage",
107
+ "type": "uint32"
108
+ },
109
+ {
110
+ "name": "freshness",
111
+ "type": "uint32"
112
+ },
113
+ {
114
+ "name": "input",
115
+ "type": "Input"
116
+ },
117
+ {
118
+ "name": "output",
119
+ "type": "Output"
120
+ }
121
+ ],
122
+ "Output": [
123
+ {
124
+ "name": "token",
125
+ "type": "address"
126
+ },
127
+ {
128
+ "name": "limit",
129
+ "type": "uint256"
130
+ },
131
+ {
132
+ "name": "triggerLower",
133
+ "type": "uint256"
134
+ },
135
+ {
136
+ "name": "triggerUpper",
137
+ "type": "uint256"
138
+ },
139
+ {
140
+ "name": "recipient",
141
+ "type": "address"
142
+ }
143
+ ],
144
+ "TokenPermissions": [
145
+ {
146
+ "name": "token",
147
+ "type": "address"
148
+ },
149
+ {
150
+ "name": "amount",
151
+ "type": "uint256"
152
+ }
153
+ ]
154
+ },
155
+ "message": {
156
+ "permitted": {
157
+ "token": "<INTOKEN>",
158
+ "amount": "<INTOTALAMOUNT>"
159
+ },
160
+ "spender": "<REACTOR>",
161
+ "nonce": "<NONCE>",
162
+ "deadline": "<DEADLINE>",
163
+ "witness": {
164
+ "reactor": "<REACTOR>",
165
+ "executor": "<EXECUTOR>",
166
+ "exchange": {
167
+ "adapter": "<ADAPTER>",
168
+ "ref": "<REFERRER>",
169
+ "share": "<REFSHAREBPS>",
170
+ "data": "<ADAPTER_USER_DATA>"
171
+ },
172
+ "swapper": "<SWAPPER>",
173
+ "nonce": "<NONCE>",
174
+ "start": "<START>",
175
+ "deadline": "<DEADLINE>",
176
+ "chainid": "<CHAINID>",
177
+ "exclusivity": "<EXCLUSIVITYBPS>",
178
+ "epoch": "<EPOCHSECONDS>",
179
+ "slippage": "<SLIPPAGEBPS>",
180
+ "freshness": "<FRESHNESSSECONDS>",
181
+ "input": {
182
+ "token": "<INTOKEN>",
183
+ "amount": "<INCHUNKAMOUNT>",
184
+ "maxAmount": "<INTOTALAMOUNT>"
185
+ },
186
+ "output": {
187
+ "token": "<OUTTOKEN>",
188
+ "limit": "<OUTAMOUNTMIN>",
189
+ "triggerLower": "<OUTAMOUNTTRIGGERLOWER>",
190
+ "triggerUpper": "<OUTAMOUNTTRIGGERUPPER>",
191
+ "recipient": "<RECIPIENT>"
192
+ }
193
+ }
194
+ }
195
+ }
@@ -0,0 +1,97 @@
1
+ # Common Token Addressbook
2
+
3
+ ## Ethereum (`1`)
4
+
5
+ 1. `weth`: `0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2`
6
+ 2. `wbtc`: `0x2260FAC5E5542a773Aa44fBCfeDf7C193bc2C599`
7
+ 3. `usdc`: `0xA0b86991c6218b36c1d19D4a2e9Eb0cE3606eB48`
8
+ 4. `usdt`: `0xdAC17F958D2ee523a2206206994597C13D831ec7`
9
+ 5. `dai`: `0x6B175474E89094C44Da98b954EedeAC495271d0F`
10
+ 6. `lusd`: `0x5f98805A4E8be255a32880FDeC7F6728C6568bA0`
11
+ 7. `orbs`: `0xff56Cc6b1E6dEd347aA0B7676C85AB0B3D08B0FA`
12
+
13
+ ## BNB Chain (`56`)
14
+
15
+ 1. `wbnb`: `0xbb4CdB9CBd36B01bD1cBaEBF2De08d9173bc095c`
16
+ 2. `btcb`: `0x7130d2A12B9BCbFAe4f2634d864A1Ee1Ce3Ead9c`
17
+ 3. `wbtc`: `0x0555e30da8f98308edb960aa94c0db47230d2b9c`
18
+ 4. `usdc`: `0x8AC76a51cc950d9822D68b83fE1Ad97B32Cd580d`
19
+ 5. `usdt`: `0x55d398326f99059fF775485246999027B3197955`
20
+ 6. `usd1`: `0x8d0d000ee44948fc98c9b98a4fa4921476f08b0d`
21
+ 7. `dai`: `0x1AF3F329e8BE154074D8769D1FFa4eE058B1DBc3`
22
+ 8. `busd`: `0xe9e7CEA3DedcA5984780Bafc599bD69ADd087D56`
23
+ 9. `weth`: `0x2170Ed0880ac9A755fd29B2688956BD959F933F8`
24
+ 10. `orbs`: `0x43a8cab15D06d3a5fE5854D714C37E7E9246F170`
25
+
26
+ ## Polygon (`137`)
27
+
28
+ 1. `wmatic`: `0x0d500B1d8E8eF31E21C99d1Db9A6444d3ADf1270`
29
+ 2. `wbtc`: `0x1BFD67037B42Cf73acF2047067bd4F2C47D9BfD6`
30
+ 3. `usdc`: `0x3c499c542cEF5E3811e1192ce70d8cC03d5c3359`
31
+ 4. `usdc.e`: `0x2791Bca1f2de4661ED88A30C99A7a9449Aa84174`
32
+ 5. `usdt`: `0xc2132D05D31c914a87C6611C10748AEb04B58e8F`
33
+ 6. `dai`: `0x8f3Cf7ad23Cd3CaDbD9735AFf958023239c6A063`
34
+ 7. `weth`: `0x7ceb23fd6bc0add59e62ac25578270cff1b9f619`
35
+ 8. `orbs`: `0x614389EaAE0A6821DC49062D56BDA3d9d45Fa2ff`
36
+
37
+ ## Arbitrum One (`42161`)
38
+
39
+ 1. `weth`: `0x82af49447d8a07e3bd95bd0d56f35241523fbab1`
40
+ 2. `wbtc`: `0x2f2a2543b76a4166549f7aab2e75bef0aefc5b0f`
41
+ 3. `usdc`: `0xaf88d065e77c8cC2239327C5EDb3A432268e5831`
42
+ 4. `usdt`: `0xfd086bc7cd5c481dcc9c85ebe478a1c0b69fcbb9`
43
+ 5. `dai`: `0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1`
44
+ 6. `arb`: `0x912CE59144191C1204E64559FE8253a0e49E6548`
45
+ 7. `orbs`: `0xf3C091ed43de9c270593445163a41A876A0bb3dd`
46
+
47
+ ## Optimism (`10`)
48
+
49
+ 1. `weth`: `0x4200000000000000000000000000000000000006`
50
+ 2. `wbtc`: `0x68f180fcCe6836688e9084f035309E29Bf0A2095`
51
+ 3. `usdc`: `0x7F5c764cBc14f9669B88837ca1490cCa17c31607`
52
+ 4. `usdt`: `0x94b008aA00579c1307B0EF2c499aD98a8ce58e58`
53
+ 5. `dai`: `0xDA10009cBd5D07dd0CeCc66161FC93D7c9000da1`
54
+ 6. `op`: `0x4200000000000000000000000000000000000042`
55
+
56
+ ## Avalanche (`43114`)
57
+
58
+ 1. `wavax`: `0xB31f66AA3C1e785363F0875A1B74E27b85FD66c7`
59
+ 2. `wbtc`: `0x50b7545627a5162F82A992c33b87aDc75187B218`
60
+ 3. `usdc`: `0xA7D7079b0FEaD91F3e65f86E8915Cb59c1a4C664`
61
+ 4. `usdt`: `0xc7198437980c041c805A1EDcbA50c1Ce5db95118`
62
+ 5. `dai`: `0xd586E7F844cEa2F87f50152665BCbc2C279D8d70`
63
+ 6. `weth`: `0x49D5c2BdFfac6CE2BFdB6640F4F80f226bc10bAB`
64
+ 7. `orbs`: `0x340fE1D898ECCAad394e2ba0fC1F93d27c7b717A`
65
+
66
+ ## Base (`8453`)
67
+
68
+ 1. `weth`: `0x4200000000000000000000000000000000000006`
69
+ 2. `usdc`: `0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913`
70
+ 3. `dai`: `0x50c5725949A6F0c72E6C4a641F24049A917DB0Cb`
71
+ 4. `cbbtc`: `0xcbb7c0000ab88b473b1f5afd9ef808440eed33bf`
72
+
73
+ ## Mantle (`5000`)
74
+
75
+ 1. `wmnt`: `0x78c1b0C915c4FAA5FffA6CAbf0219DA63d7f4cb8`
76
+ 2. `weth`: `0xdeaddeaddeaddeaddeaddeaddeaddeaddead1111`
77
+ 3. `usdc`: `0x09Bc4E0D864854c6aFB6eB9A9cdF58aC190D0dF9`
78
+ 4. `usdt`: `0x201eba5cc46D216Ce6DC03F6a759e8E766e956Ae`
79
+ 5. `usdt0`: `0x779Ded0c9e1022225f8E0630b35a9b54bE713736`
80
+
81
+ ## Linea (`59144`)
82
+
83
+ 1. `weth`: `0xe5D7C2a44FfDDf6b295A15c148167daaAf5Cf34f`
84
+ 2. `wbtc`: `0x3aAB2285ddcDdaD8edf438C1bAB47e1a9D05a9b4`
85
+ 3. `usdc`: `0x176211869cA2b568f2A7D4EE941E073a821EE1ff`
86
+ 4. `usdt`: `0xA219439258ca9da29E9Cc4cE5596924745e12B93`
87
+ 5. `dai`: `0x4AF15ec2A0BD43Db75dd04E62FAA3B8EF36b00d5`
88
+
89
+ ## Sonic (`146`)
90
+
91
+ 1. `ws`: `0x039e2fB66102314Ce7b64Ce5Ce3E5183bc94aD38`
92
+ 2. `wbtc`: `0x0555E30da8f98308EdB960aa94C0Db47230d2B9c`
93
+ 3. `weth`: `0x50c42dEAcD8Fc9773493ED674b675bE577f2634b`
94
+ 4. `usdc`: `0x29219dd400f2Bf60E5a23d13Be72B486D4038894`
95
+ 5. `usdt`: `0x6047828dc181963ba44974801FF68e538dA5eaF9`
96
+ 6. `sfc`: `0xFC00FACE00000000000000000000000000000000`
97
+
@@ -0,0 +1,111 @@
1
+ // Example only. This flow uses eth_signTypedData_v4 via an injected provider,
2
+ // but any framework that signs the same prepared.typedData payload is valid.
3
+
4
+ import Web3 from "web3";
5
+
6
+ const DEPOSIT_DATA = "0xd0e30db0";
7
+ const ERC20_ABI = [
8
+ {
9
+ constant: true,
10
+ inputs: [
11
+ { name: "owner", type: "address" },
12
+ { name: "spender", type: "address" },
13
+ ],
14
+ name: "allowance",
15
+ outputs: [{ name: "", type: "uint256" }],
16
+ type: "function",
17
+ },
18
+ ];
19
+
20
+ export async function approveSignAndSubmitOrder({
21
+ prepared,
22
+ account,
23
+ provider = window.ethereum,
24
+ wrappedNative,
25
+ nativeInputAmount,
26
+ sendApproval = true,
27
+ }) {
28
+ const web3 = new Web3(provider);
29
+ const normalizedAccount = account.toLowerCase();
30
+ const expectedSigner = prepared.signing.signer.toLowerCase();
31
+
32
+ // The EIP-712 signer must be the same address that created the order.
33
+ if (normalizedAccount !== expectedSigner) {
34
+ throw new Error(
35
+ `signer mismatch: expected ${prepared.signing.signer}, got ${account}`
36
+ );
37
+ }
38
+
39
+ // Native input is not supported by the order itself.
40
+ // If the input starts as the chain's native asset, wrap it to WNATIVE first.
41
+ if (
42
+ nativeInputAmount != null &&
43
+ nativeInputAmount !== "0" &&
44
+ nativeInputAmount !== "0x0"
45
+ ) {
46
+ if (!wrappedNative) {
47
+ throw new Error("wrappedNative is required when nativeInputAmount is set");
48
+ }
49
+
50
+ await web3.eth.sendTransaction({
51
+ from: account,
52
+ to: wrappedNative,
53
+ data: DEPOSIT_DATA,
54
+ value: nativeInputAmount,
55
+ });
56
+ }
57
+
58
+ if (prepared.approval && sendApproval) {
59
+ // The skill helper is RPC-agnostic, so the caller should use its own
60
+ // provider access to avoid resending the same infinite approval.
61
+ const token = new web3.eth.Contract(ERC20_ABI, prepared.approval.tx.to);
62
+ const allowance = BigInt(
63
+ await token.methods
64
+ .allowance(account, prepared.approval.spender)
65
+ .call()
66
+ );
67
+
68
+ if (allowance < BigInt(prepared.approval.amount)) {
69
+ await web3.eth.sendTransaction({
70
+ from: account,
71
+ to: prepared.approval.tx.to,
72
+ data: prepared.approval.tx.data,
73
+ value: prepared.approval.tx.value,
74
+ });
75
+ }
76
+ }
77
+
78
+ // This example uses eth_signTypedData_v4, but any equivalent EIP-712 signer works.
79
+ const signature = await provider.request({
80
+ method: "eth_signTypedData_v4",
81
+ params: [account, JSON.stringify(prepared.typedData)],
82
+ });
83
+
84
+ // Submit the order payload plus the returned signature to the relay endpoint.
85
+ const response = await fetch(prepared.submit.url, {
86
+ method: "POST",
87
+ headers: {
88
+ "content-type": "application/json",
89
+ },
90
+ body: JSON.stringify({
91
+ ...prepared.submit.body,
92
+ signature,
93
+ }),
94
+ });
95
+
96
+ const text = await response.text();
97
+ let body;
98
+
99
+ try {
100
+ body = JSON.parse(text);
101
+ } catch {
102
+ body = text;
103
+ }
104
+
105
+ return {
106
+ ok: response.ok,
107
+ status: response.status,
108
+ signature,
109
+ body,
110
+ };
111
+ }
package/package.json ADDED
@@ -0,0 +1,30 @@
1
+ {
2
+ "name": "@orbs-network/spot-skill",
3
+ "version": "2.4.0",
4
+ "description": "Use for gasless non-custodial EVM market, limit, TWAP, stop-loss, take-profit, delayed-start orders.",
5
+ "homepage": "https://orbs-network.github.io/spot/",
6
+ "bugs": {
7
+ "url": "https://github.com/orbs-network/spot/issues"
8
+ },
9
+ "repository": {
10
+ "type": "git",
11
+ "url": "git+https://github.com/orbs-network/spot.git",
12
+ "directory": "skill"
13
+ },
14
+ "license": "MIT",
15
+ "author": "danielz@orbs.com",
16
+ "engines": {
17
+ "node": ">=18"
18
+ },
19
+ "files": [
20
+ "SKILL.md",
21
+ "references/01-quickstart.md",
22
+ "references/02-params.md",
23
+ "references/03-sign.md",
24
+ "references/04-patterns.md",
25
+ "assets/token-addressbook.md",
26
+ "assets/repermit.skeleton.json",
27
+ "assets/web3-sign-and-submit.example.js",
28
+ "scripts/order.js"
29
+ ]
30
+ }
@@ -0,0 +1,12 @@
1
+ # Quickstart
2
+
3
+ 1. Required fields: `chainId`, `swapper`, `input.token`, `input.amount`, `output.token`.
4
+ 2. Choose the intended order shape before preparing: market, limit, stop-loss, take-profit, delayed-start, or chunked/TWAP.
5
+ 3. Prepare the order with the helper.
6
+ 4. If approval is needed, send `prepared.approval.tx` to approve `RePermit`.
7
+ 5. The skill helper does not read allowance onchain. The calling agent or app should use its own RPC or provider access to compare the current ERC-20 allowance against `prepared.approval.amount`, send that infinite approval only when allowance is lower, and then leave the infinite approval in place with no reset.
8
+ 6. Sign `prepared.typedData` as the `swapper`.
9
+ 7. Submit the signed order.
10
+ 8. Query the order by `swapper` or `hash`.
11
+ 9. Watch until terminal state. Default polling is every 5 seconds, timeout `0` means no timeout, and transient network errors are retried automatically.
12
+ 10. When measuring a fill onchain, sum both transfers to the swapper: the main fill and the surplus refund. Measuring only the main fill undercounts actual output by up to the slippage tolerance.
@@ -0,0 +1,39 @@
1
+ # Params
2
+
3
+ Use this file for field semantics, defaults, units, and validation.
4
+
5
+ 1. Required: `chainId`, `swapper`, `input.token`, `input.amount`, `output.token`.
6
+ 2. Optional: `input.maxAmount`, `nonce`, `start`, `deadline`, `epoch`, `slippage`, `output.limit`, `output.triggerLower`, `output.triggerUpper`, `output.recipient`.
7
+ 3. `input.amount` is the fixed per-chunk size. `input.maxAmount` is the total requested size. If omitted, it defaults to `input.amount`. If it is not divisible by `input.amount`, the helper rounds it down to a whole number of chunks.
8
+ 4. `output.limit`, `output.triggerLower`, and `output.triggerUpper` are output-token amounts per chunk, encoded in the output token's decimals.
9
+ 5. Future `start` delays the first fill. `epoch` is the delay between chunks, but it is not exact: each chunk can fill anywhere inside its epoch window, only once. Large `epoch` is not a delayed order by itself.
10
+ 6. Chunked orders should use `epoch > 0`; with `epoch = 0`, only the first chunk can fill.
11
+ 7. Defaults:
12
+ - `input.maxAmount = input.amount`
13
+ - `nonce = now`
14
+ - `start = now`
15
+ - `epoch = 0` for single orders, `60` for chunked orders
16
+ - `deadline = start + 300 + chunkCount * epoch`
17
+ - `slippage = 500`
18
+ - `output.limit = 0`
19
+ - `output.recipient = swapper`
20
+ 8. Higher slippage is still protected by oracle pricing and offchain executors.
21
+ 9. `output.recipient` is dangerous to change away from `swapper`.
22
+ 10. Native input is not supported. Wrap to WNATIVE first. Native output, including "back to native" orders, is supported directly with `output.token = 0x0000000000000000000000000000000000000000`.
23
+ 11. Example:
24
+
25
+ ```json
26
+ {
27
+ "chainId": 42161,
28
+ "swapper": "0x1111111111111111111111111111111111111111",
29
+ "input": {
30
+ "token": "0xaf88d065e77c8cC2239327C5EDb3A432268e5831",
31
+ "amount": "1000000"
32
+ },
33
+ "output": {
34
+ "token": "0x82af49447d8a07e3bd95bd0d56f35241523fbab1",
35
+ "limit": "0"
36
+ },
37
+ "epoch": 3600
38
+ }
39
+ ```
@@ -0,0 +1,6 @@
1
+ # Sign And Submit
2
+
3
+ 1. Sign `prepared.typedData` with any EIP-712-capable wallet or library. The signer must equal `swapper`. `eth_signTypedData_v4` is only one example.
4
+ 2. Submit with `--prepared <prepared.json|->` and exactly one signature mode: `--signature <0x...|json>`, `--signature-file <sig.txt|sig.json|->`, or `--r <0x...> --s <0x...> --v <0x...>`.
5
+ 3. The helper accepts a full 65-byte signature, a JSON string, or JSON/object `r/s/v`.
6
+ 4. Cancel trustlessly onchain by calling `RePermit.cancel([digest])` as the swapper for the signed RePermit digest.
@@ -0,0 +1,12 @@
1
+ # Order Patterns
2
+
3
+ 1. Market swap: `input.amount = input.maxAmount`, `output.limit = 0`.
4
+ 2. Limit order: `input.amount = input.maxAmount`, `output.limit > 0`.
5
+ 3. Stop-loss or take-profit: set `output.triggerLower` for stop-loss and/or `output.triggerUpper` for take-profit.
6
+ 4. Delayed order: set future `start`.
7
+ 5. Chunked or TWAP-style: set `input.amount < input.maxAmount`.
8
+ 6. Time-spaced chunked order: set `epoch > 0`. For example, `epoch = 60` means one chunk can fill once anywhere inside each 60-second epoch window.
9
+ 7. `N chunks`: use one TWAP order instead of manually submitting `N` separate orders. Use `input.maxAmount` as the requested total amount, set `input.amount = floor(total / N)`, and accept any rounded-down remainder as dust.
10
+ 8. If timing is omitted for a chunked or TWAP order, `epoch` defaults to `60`. Single orders default to `0`.
11
+ 9. Native output or back to native exposure: set `output.token = 0x0000000000000000000000000000000000000000`.
12
+ 10. Best execution and oracle protection apply regardless of `output.limit`.