|
19 | 19 | ], |
20 | 20 | "methods": [ |
21 | 21 | { |
22 | | - "name": "client_signAndSendTransactionWithIntent", |
| 22 | + "name": "signAndSendTransactionWithIntent", |
23 | 23 | "summary": "Sign and send a transaction with verified intent", |
24 | 24 | "description": "Allows the client (MetaMask) to request the snap to sign and send a transaction with verified intent.\n\n**Process:**\n\n1. **Verify Backend Signature** - Ensures that the payload **{ intent, signature }** was signed by the trusted Swaps API\n2. **Match Transaction to Intent** - Verifies that the transaction performs exactly what the intent describes\n3. **Sign Transaction** - If all validation pass, signs the transaction with the user's account specified in the intent\n4. **Send Transaction** - Sends the transaction to the Solana network", |
| 25 | + "paramStructure": "by-name", |
25 | 26 | "params": [ |
26 | 27 | { |
27 | 28 | "name": "intent", |
28 | | - "summary": "The user's intent describing the desired swap/bridge operation", |
| 29 | + "summary": "The user's swap intent describing the desired operation", |
29 | 30 | "required": true, |
30 | 31 | "schema": { |
31 | | - "$ref": "#/components/schemas/Intent" |
| 32 | + "$ref": "#/components/schemas/SwapIntent" |
32 | 33 | } |
33 | 34 | }, |
34 | 35 | { |
35 | 36 | "name": "transaction", |
36 | 37 | "summary": "The base64-encoded transaction to sign and send", |
37 | 38 | "required": true, |
38 | 39 | "schema": { |
39 | | - "type": "string" |
| 40 | + "$ref": "#/components/schemas/Base64String" |
40 | 41 | } |
41 | 42 | }, |
42 | 43 | { |
|
55 | 56 | "$ref": "#/components/schemas/SignAndSendTransactionWithIntentResult" |
56 | 57 | } |
57 | 58 | }, |
| 59 | + "errors": [ |
| 60 | + { |
| 61 | + "$ref": "#/components/errors/MethodNotFound" |
| 62 | + }, |
| 63 | + { |
| 64 | + "$ref": "#/components/errors/InvalidParams" |
| 65 | + }, |
| 66 | + { |
| 67 | + "$ref": "#/components/errors/InvalidBackendSignature" |
| 68 | + }, |
| 69 | + { |
| 70 | + "$ref": "#/components/errors/TransactionIntentMismatch" |
| 71 | + }, |
| 72 | + { |
| 73 | + "$ref": "#/components/errors/AccountNotFound" |
| 74 | + }, |
| 75 | + { |
| 76 | + "$ref": "#/components/errors/InvalidTransaction" |
| 77 | + }, |
| 78 | + { |
| 79 | + "$ref": "#/components/errors/TransactionFailed" |
| 80 | + } |
| 81 | + ], |
58 | 82 | "examples": [ |
59 | 83 | { |
60 | 84 | "name": "signAndSendTransactionWithIntentExample", |
|
64 | 88 | "name": "intent", |
65 | 89 | "value": { |
66 | 90 | "id": "c76b3834-b9a8-4dfd-91da-72c26a216fb2", |
67 | | - "timestamp": "2021-01-01T00:00:00Z", |
68 | | - "accountId": "9ce0cc70-9c04-48f7-a3dc-d9c1496ac229", |
| 91 | + "timestamp": "2025-06-04T14:52:31.307Z", |
| 92 | + "type": "swap", |
| 93 | + "slippage": 0.01, |
69 | 94 | "from": { |
70 | | - "assetType": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501", |
| 95 | + "address": "BLw3RweJmfbTapJRgnPRvd962YDjFYAnVGd1p5hmZ5tP", |
| 96 | + "asset": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501", |
71 | 97 | "amount": "1000000000" |
72 | 98 | }, |
73 | 99 | "to": { |
74 | | - "assetType": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", |
| 100 | + "address": "27h6cm6S9ag5y4ASi1a1vbTSKEsQMjEdfvZ6atPjmbuD", |
| 101 | + "asset": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", |
75 | 102 | "amount": "161180000" |
76 | 103 | } |
77 | 104 | } |
|
88 | 115 | "result": { |
89 | 116 | "name": "signAndSendTransactionWithIntentResult", |
90 | 117 | "value": { |
91 | | - "signature": "DuvWiKG54eKcB1s777TgaZWtF9R23sVuEaugRufdXyqhCf6owy5hYqxeL8sa6zoCPVQu3NxxhjWuz91CKgLE6SB", |
92 | | - "intent": { |
93 | | - "id": "c76b3834-b9a8-4dfd-91da-72c26a216fb2", |
94 | | - "timestamp": "2021-01-01T00:00:00Z", |
95 | | - "accountId": "9ce0cc70-9c04-48f7-a3dc-d9c1496ac229", |
96 | | - "from": { |
97 | | - "assetType": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501", |
98 | | - "amount": "1000000000" |
99 | | - }, |
100 | | - "to": { |
101 | | - "assetType": "solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/token:EPjFWdd5AufqSSqeM2qN1xzybapC8G4wEGGkZwyTDt1v", |
102 | | - "amount": "161180000" |
103 | | - } |
104 | | - } |
| 118 | + "transactionId": "DuvWiKG54eKcB1s777TgaZWtF9R23sVuEaugRufdXyqhCf6owy5hYqxeL8sa6zoCPVQu3NxxhjWuz91CKgLE6SB" |
105 | 119 | } |
106 | 120 | } |
107 | 121 | } |
|
114 | 128 | "type": "string", |
115 | 129 | "format": "date-time", |
116 | 130 | "description": "An ISO 8601 timestamp", |
117 | | - "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}\\.\\d{3}Z$", |
| 131 | + "pattern": "^\\d{4}-\\d{2}-\\d{2}T\\d{2}:\\d{2}:\\d{2}(\\.\\d{3})?Z$", |
118 | 132 | "examples": ["2021-01-01T00:00:00Z", "2021-01-01T00:00:00.000Z"] |
119 | 133 | }, |
120 | 134 | "UuidV4": { |
|
127 | 141 | "6ba7b810-9dad-11d1-80b4-00c04fd430c8" |
128 | 142 | ] |
129 | 143 | }, |
130 | | - "Intent": { |
| 144 | + "Base64String": { |
| 145 | + "type": "string", |
| 146 | + "description": "A base64-encoded string", |
| 147 | + "pattern": "^[A-Za-z0-9+/]*={0,2}$" |
| 148 | + }, |
| 149 | + "SwapIntent": { |
131 | 150 | "type": "object", |
132 | | - "description": "Represents a user's intent to perform a swap or bridge operation", |
| 151 | + "description": "Represents a user's intent to perform a swap operation", |
133 | 152 | "properties": { |
134 | 153 | "id": { |
135 | 154 | "$ref": "#/components/schemas/UuidV4", |
|
139 | 158 | "$ref": "#/components/schemas/Iso8601Timestamp", |
140 | 159 | "description": "ISO 8601 timestamp when the intent was created" |
141 | 160 | }, |
142 | | - "accountId": { |
| 161 | + "type": { |
143 | 162 | "type": "string", |
144 | | - "description": "The identifier of the account to sign the transaction with" |
| 163 | + "enum": ["swap"], |
| 164 | + "description": "The type of operation - must be 'swap'" |
| 165 | + }, |
| 166 | + "slippage": { |
| 167 | + "type": "number", |
| 168 | + "description": "Maximum acceptable slippage percentage", |
| 169 | + "minimum": 0, |
| 170 | + "maximum": 100 |
145 | 171 | }, |
146 | 172 | "from": { |
147 | | - "$ref": "#/components/schemas/AssetAmount", |
| 173 | + "$ref": "#/components/schemas/AssetTransfer", |
148 | 174 | "description": "The asset and amount the user wants to send" |
149 | 175 | }, |
150 | 176 | "to": { |
151 | | - "$ref": "#/components/schemas/AssetAmount", |
| 177 | + "$ref": "#/components/schemas/AssetTransfer", |
152 | 178 | "description": "The asset and amount the user expects to receive" |
153 | 179 | } |
154 | 180 | }, |
155 | | - "required": ["id", "timestamp", "accountId", "from", "to"], |
| 181 | + "required": ["id", "timestamp", "type", "slippage", "from", "to"], |
156 | 182 | "additionalProperties": false |
157 | 183 | }, |
158 | | - "AssetAmount": { |
| 184 | + "AssetTransfer": { |
159 | 185 | "type": "object", |
160 | | - "description": "Represents an asset and its amount", |
| 186 | + "description": "Represents an asset transfer with address, asset type, and amount", |
161 | 187 | "properties": { |
162 | | - "assetType": { |
| 188 | + "address": { |
163 | 189 | "type": "string", |
164 | | - "description": "CAIP-19 asset type (e.g., 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501' for SOL)" |
| 190 | + "description": "A CAIP-10 account address, i.e., the third part of the CAIP account ID. For example, 'BLw3RweJmfbTapJRgnPRvd962YDjFYAnVGd1p5hmZ5tP'." |
| 191 | + }, |
| 192 | + "asset": { |
| 193 | + "type": "string", |
| 194 | + "description": "A CAIP-19 asset type identifier, i.e., a human-readable type of asset identifier. For example, 'solana:5eykt4UsFv8P8NJdTREpY1vzqKqZKvdp/slip44:501'." |
165 | 195 | }, |
166 | 196 | "amount": { |
167 | 197 | "type": "string", |
168 | | - "description": "Amount in the asset's smallest unit (e.g., lamports for SOL)" |
| 198 | + "description": "Amount in the asset's smallest unit (e.g., lamports for SOL)", |
| 199 | + "pattern": "^[0-9]+$" |
| 200 | + }, |
| 201 | + "change": { |
| 202 | + "type": "object", |
| 203 | + "description": "Optional change address for the transaction", |
| 204 | + "properties": { |
| 205 | + "address": { |
| 206 | + "type": "string", |
| 207 | + "description": "CAIP-10 account address for change" |
| 208 | + } |
| 209 | + }, |
| 210 | + "required": ["address"], |
| 211 | + "additionalProperties": false |
169 | 212 | } |
170 | 213 | }, |
171 | | - "required": ["assetType", "amount"], |
| 214 | + "required": ["address", "asset", "amount"], |
172 | 215 | "additionalProperties": false |
173 | 216 | }, |
174 | 217 | "SignAndSendTransactionWithIntentResult": { |
175 | 218 | "type": "object", |
176 | 219 | "description": "Result of signing and sending a transaction with intent", |
177 | 220 | "properties": { |
178 | | - "signature": { |
| 221 | + "transactionId": { |
179 | 222 | "type": "string", |
180 | 223 | "description": "The transaction signature returned after successful execution on Solana" |
181 | | - }, |
182 | | - "intent": { |
183 | | - "$ref": "#/components/schemas/Intent", |
184 | | - "description": "The original intent that was fulfilled, returned for assurance that the intent was fulfilled" |
185 | 224 | } |
186 | 225 | }, |
187 | | - "required": ["signature", "intent"], |
| 226 | + "required": ["transactionId"], |
188 | 227 | "additionalProperties": false |
189 | 228 | } |
| 229 | + }, |
| 230 | + "errors": { |
| 231 | + "MethodNotFound": { |
| 232 | + "code": -32601, |
| 233 | + "message": "The method does not exist / is not available.", |
| 234 | + "data": { |
| 235 | + "type": "object", |
| 236 | + "description": "The requested method is not supported by this handler", |
| 237 | + "properties": { |
| 238 | + "method": { |
| 239 | + "type": "string", |
| 240 | + "description": "The method that was requested" |
| 241 | + } |
| 242 | + } |
| 243 | + } |
| 244 | + }, |
| 245 | + "InvalidParams": { |
| 246 | + "code": -32602, |
| 247 | + "message": "Invalid method parameter(s).", |
| 248 | + "data": { |
| 249 | + "type": "object", |
| 250 | + "description": "The parameters provided do not match the expected schema" |
| 251 | + } |
| 252 | + }, |
| 253 | + "InvalidBackendSignature": { |
| 254 | + "code": -32602, |
| 255 | + "message": "Invalid backend signature", |
| 256 | + "data": { |
| 257 | + "type": "object", |
| 258 | + "description": "The backend signature verification failed", |
| 259 | + "properties": { |
| 260 | + "reason": { |
| 261 | + "type": "string", |
| 262 | + "enum": [ |
| 263 | + "signatureVerificationFailed", |
| 264 | + "timestampExpired", |
| 265 | + "invalidSignatureFormat", |
| 266 | + "missingPublicKey" |
| 267 | + ], |
| 268 | + "description": "The specific reason why signature verification failed" |
| 269 | + } |
| 270 | + } |
| 271 | + } |
| 272 | + }, |
| 273 | + "TransactionIntentMismatch": { |
| 274 | + "code": -32602, |
| 275 | + "message": "Transaction does not match intent", |
| 276 | + "data": { |
| 277 | + "type": "object", |
| 278 | + "description": "The transaction does not perform the operations described in the intent", |
| 279 | + "properties": { |
| 280 | + "reason": { |
| 281 | + "type": "string", |
| 282 | + "enum": [ |
| 283 | + "amountMismatch", |
| 284 | + "assetMismatch", |
| 285 | + "addressMismatch", |
| 286 | + "unexpectedInstructions", |
| 287 | + "simulationFailed" |
| 288 | + ], |
| 289 | + "description": "The specific reason why the transaction doesn't match the intent" |
| 290 | + } |
| 291 | + } |
| 292 | + } |
| 293 | + }, |
| 294 | + "AccountNotFound": { |
| 295 | + "code": -32602, |
| 296 | + "message": "Account not found", |
| 297 | + "data": { |
| 298 | + "type": "object", |
| 299 | + "description": "The account specified in the intent was not found in the keyring", |
| 300 | + "properties": { |
| 301 | + "address": { |
| 302 | + "type": "string", |
| 303 | + "description": "The account address that was not found" |
| 304 | + } |
| 305 | + } |
| 306 | + } |
| 307 | + }, |
| 308 | + "InvalidTransaction": { |
| 309 | + "code": -32602, |
| 310 | + "message": "Invalid transaction", |
| 311 | + "data": { |
| 312 | + "type": "object", |
| 313 | + "description": "The transaction is malformed or cannot be processed", |
| 314 | + "properties": { |
| 315 | + "reason": { |
| 316 | + "type": "string", |
| 317 | + "enum": [ |
| 318 | + "invalidBase64Encoding", |
| 319 | + "malformedTransaction", |
| 320 | + "invalidTransactionStructure", |
| 321 | + "missingRequiredFields" |
| 322 | + ], |
| 323 | + "description": "The specific reason why the transaction is invalid" |
| 324 | + } |
| 325 | + } |
| 326 | + } |
| 327 | + }, |
| 328 | + "TransactionFailed": { |
| 329 | + "code": -32603, |
| 330 | + "message": "Transaction failed", |
| 331 | + "data": { |
| 332 | + "type": "object", |
| 333 | + "description": "The transaction was rejected by the Solana network", |
| 334 | + "properties": { |
| 335 | + "reason": { |
| 336 | + "type": "string", |
| 337 | + "enum": [ |
| 338 | + "insufficientBalance", |
| 339 | + "blockhashExpired", |
| 340 | + "accountNotFound", |
| 341 | + "programError", |
| 342 | + "instructionError", |
| 343 | + "simulationFailed" |
| 344 | + ], |
| 345 | + "description": "The specific reason why the transaction failed" |
| 346 | + } |
| 347 | + } |
| 348 | + } |
| 349 | + } |
190 | 350 | } |
191 | 351 | } |
192 | 352 | } |
0 commit comments