|
271 | 271 | { |
272 | 272 | "data": { |
273 | 273 | "text/plain": [ |
274 | | - "(200, [{'id': 1, 'balance': 4396, 'currency': 'usd'}])" |
| 274 | + "(200, [{'id': 15, 'balance': 87, 'currency': 'usd'}])" |
275 | 275 | ] |
276 | 276 | }, |
277 | 277 | "execution_count": null, |
|
487 | 487 | "data": { |
488 | 488 | "text/plain": [ |
489 | 489 | "(200,\n", |
490 | | - " {'expires_at': '2025-04-23T13:10:12.330724+00:00',\n", |
| 490 | + " {'expires_at': '2025-04-28T16:43:07.985112+00:00',\n", |
491 | 491 | " 'offer_id': 'test_offer_2',\n", |
492 | | - " 'payment_request': {'lightning_invoice': 'lnbc100n1p5q3h5ppp54neu5ukgkshem4j6yyx4gdpuscj8psy92f52jhgzxsts6az02twsdq523jhxapq2pskx6mpvajscqzpgxqrzpnrzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp52p0m2rgrd8v6peyxm2dqwwyfn32wmls3x74thr890h0rx2nt3h2q9qxpqysgqu6rsscdg76jng554uj7pt7ln7kage37u9t2ut4208suzvu5e4hw5n2ssa4dhmfpgc0mgmywzvya9902sg8re846pn6f4fkl3vhpa80cp7jqjjr'},\n", |
| 492 | + " 'payment_request': {'lightning_invoice': 'lnbc100n1p5qlflfpp50zwmzn36u93u7hcnhyjtqgsa65lnrrzfymeetv6uyqrltnktpesqdq523jhxapq2pskx6mpvajscqzpgxqrzpjrzjqwghf7zxvfkxq5a6sr65g0gdkv768p83mhsnt0msszapamzx2qvuxqqqqz99gpz55yqqqqqqqqqqqqqq9qrzjq25carzepgd4vqsyn44jrk85ezrpju92xyrk9apw4cdjh6yrwt5jgqqqqz99gpz55yqqqqqqqqqqqqqq9qsp5kppjx7rg9kq0ugvgn4vkcfa4z34ytcjtylcfxhs3dwl2sr029m8s9qxpqysgqtgunz5j2wkm5845qmvk2m7yz5nnqwtpnhqteawq97wv3m9xneeusjuj7xjp88078th6rtx09ad7zt3cc3l5dd3w9hkakfpkw3vvm0ugqgm2lc4'},\n", |
493 | 493 | " 'version': '0.2.2'})" |
494 | 494 | ] |
495 | 495 | }, |
|
560 | 560 | "cell_type": "markdown", |
561 | 561 | "metadata": {}, |
562 | 562 | "source": [ |
563 | | - "## Webhooks\n", |
| 563 | + "### Webhooks\n", |
564 | 564 | "\n", |
565 | 565 | "Use this as a vendor to get notified when someone pays for your offer. Currently only 1 webhook is supported per user." |
566 | 566 | ] |
|
710 | 710 | "cell_type": "markdown", |
711 | 711 | "metadata": {}, |
712 | 712 | "source": [ |
| 713 | + "## Pay Methods\n", |
| 714 | + "\n", |
713 | 715 | "### Pay Lightning Invoice\n", |
714 | 716 | "\n", |
715 | 717 | "Pay lightning invoice is a low-level method to manually pay for a lightning invoice. " |
|
773 | 775 | "r = fs.pay_lightning(invoice=ln_invoice,\n", |
774 | 776 | " description=\"fewsats webhook trial\", amount=1)\n", |
775 | 777 | "lightning_payment = r.json()\n", |
776 | | - "r.status_code, lightning_payment" |
| 778 | + "r.status_code, lightning_payment\n" |
| 779 | + ] |
| 780 | + }, |
| 781 | + { |
| 782 | + "cell_type": "code", |
| 783 | + "execution_count": null, |
| 784 | + "metadata": {}, |
| 785 | + "outputs": [], |
| 786 | + "source": [ |
| 787 | + "r = fs.pay_lightning(invoice='lnbc100n1p5qlv5dpp5r4jjrenyvlndnr59nx2fgk8azyeaaxzpeuy7putgm07wfnvt398qdqqcqzzsxqrrsssp54897npsmum0av3qqj6jyvl3sks4hlc67ugdyr8x85hla79u262uq9qxpqysgq3m9p2a8j7fy2pxeg5xuhyw4zwwp6md5egkez28afffmsch2l7clhw5922mxlr52gp48w0pdvnngytgj08kn4z8uv25pq7fc0mxhrs6qphe3c0k',\n", |
| 788 | + " description=\"fewsats webhook trial\", amount=1)\n", |
| 789 | + "r.status_code, r.text" |
777 | 790 | ] |
778 | 791 | }, |
779 | 792 | { |
780 | 793 | "cell_type": "markdown", |
781 | 794 | "metadata": {}, |
782 | 795 | "source": [ |
783 | | - "### Pay Offer\n", |
| 796 | + "### Paying L402 Offers\n", |
784 | 797 | "\n", |
785 | 798 | "The pay method pays for a specific offer. The user is not required to fetch the payment details beforehand. It is asynchronous and returns the `payment_id` and `status`. Using the `payment_id` we can check the status of the payment.\n", |
786 | 799 | "\n", |
|
894 | 907 | "cell_type": "markdown", |
895 | 908 | "metadata": {}, |
896 | 909 | "source": [ |
897 | | - "### Pay Offer\n" |
| 910 | + "### Pay L402 Offer\n" |
898 | 911 | ] |
899 | 912 | }, |
900 | 913 | { |
|
964 | 977 | "cell_type": "markdown", |
965 | 978 | "metadata": {}, |
966 | 979 | "source": [ |
967 | | - "### Pay Offer with JSON string\n", |
| 980 | + "### L402 Pay Offer with JSON string\n", |
968 | 981 | "\n", |
969 | 982 | "This alternative method accepts a JSON string containing L402 offers. It should be used by systems that do not support custom classes in tool calling." |
970 | 983 | ] |
|
1163 | 1176 | "r.status_code, r.json()" |
1164 | 1177 | ] |
1165 | 1178 | }, |
| 1179 | + { |
| 1180 | + "cell_type": "markdown", |
| 1181 | + "metadata": {}, |
| 1182 | + "source": [ |
| 1183 | + "### Pay X402 Offer" |
| 1184 | + ] |
| 1185 | + }, |
| 1186 | + { |
| 1187 | + "cell_type": "code", |
| 1188 | + "execution_count": null, |
| 1189 | + "metadata": {}, |
| 1190 | + "outputs": [], |
| 1191 | + "source": [ |
| 1192 | + "#| export\n", |
| 1193 | + "\n", |
| 1194 | + "@patch\n", |
| 1195 | + "def pay_x402_offer(self:Fewsats,\n", |
| 1196 | + " payload:Dict[str, Any], # The x402 offer payload\n", |
| 1197 | + " chain:str = \"base\", # Blockchain chain to use\n", |
| 1198 | + " ) -> dict:\n", |
| 1199 | + " \"\"\"Creates a payment from an x402 offer and returns a payment header to access the resource.\n", |
| 1200 | + " \n", |
| 1201 | + " Args:\n", |
| 1202 | + " payload: The x402 offer payload containing accepts, error, and x402Version\n", |
| 1203 | + " chain: Blockchain chain to use (default: \"base\")\n", |
| 1204 | + " \n", |
| 1205 | + " Returns:\n", |
| 1206 | + " Dictionary containing payment_header to use for subsequent requests\n", |
| 1207 | + " \"\"\"\n", |
| 1208 | + " data = {\n", |
| 1209 | + " \"chain\": chain,\n", |
| 1210 | + " \"payload\": payload\n", |
| 1211 | + " }\n", |
| 1212 | + " return self._request(\"POST\", \"v0/x402/purchases/from-offer\", json=data)" |
| 1213 | + ] |
| 1214 | + }, |
| 1215 | + { |
| 1216 | + "cell_type": "code", |
| 1217 | + "execution_count": null, |
| 1218 | + "metadata": {}, |
| 1219 | + "outputs": [ |
| 1220 | + { |
| 1221 | + "data": { |
| 1222 | + "text/plain": [ |
| 1223 | + "(200,\n", |
| 1224 | + " {'payment_header': 'eyJ4NDAyVmVyc2lvbiI6IDEsICJzY2hlbWUiOiAiZXhhY3QiLCAibmV0d29yayI6ICJiYXNlLXNlcG9saWEiLCAicGF5bG9hZCI6IHsic2lnbmF0dXJlIjogIjB4MTU4NWExZjcyZjk3ZDU3ZmM3NjliZmRlNjZjNjQ0NzNlMzAxYzYwYjg0YjJiZTk5NDFiN2ZmMTRkMTc4MzIyOTQzOGRlNGI2ZGU5YjdlMzlkMDZiMmEwY2I0YTA0ZjQ1MDE5ZTExYmJjOWI5OWEyZGQ3OTQ0YTNmYzgwOTdiNjExYyIsICJhdXRob3JpemF0aW9uIjogeyJmcm9tIjogIjB4MjNiODExMDllODFGREZFOGU0MjEzNUU4M0MzMWIxMUFhN0Q5OTlBNCIsICJ0byI6ICIweGRkYjI0QmQ4QTZDYjBmMmQzZWFCRjdhODI4QzBiNDM2NDY2OEI5NjMiLCAidmFsdWUiOiAiMSIsICJ2YWxpZEFmdGVyIjogIjE3NDc0MDAyNDEiLCAidmFsaWRCZWZvcmUiOiAiMTc0NzQwMDM2MSIsICJub25jZSI6ICIweGI0ODI1M2NiMTJlMzMyNDE3N2ZiODgwYzU4OThkYzU5NmVlOGM2OWRkNGYyN2JjZTI0MGUwNzg1MzdiMTJjMzgifX19'})" |
| 1225 | + ] |
| 1226 | + }, |
| 1227 | + "execution_count": 34, |
| 1228 | + "metadata": {}, |
| 1229 | + "output_type": "execute_result" |
| 1230 | + } |
| 1231 | + ], |
| 1232 | + "source": [ |
| 1233 | + "x402_offer = {\n", |
| 1234 | + " \"accepts\": [\n", |
| 1235 | + " {\n", |
| 1236 | + " \"scheme\": \"exact\",\n", |
| 1237 | + " \"network\": \"base-sepolia\",\n", |
| 1238 | + " \"maxAmountRequired\": \"1\",\n", |
| 1239 | + " \"resource\": \"https://proxy402.com/KQzW9kfi3Z\",\n", |
| 1240 | + " \"description\": \"Payment for GET https://proxy402.com/KQzW9kfi3Z\",\n", |
| 1241 | + " \"mimeType\": \"\",\n", |
| 1242 | + " \"payTo\": \"0xddb24Bd8A6Cb0f2d3eaBF7a828C0b4364668B963\",\n", |
| 1243 | + " \"maxTimeoutSeconds\": 60,\n", |
| 1244 | + " \"asset\": \"0x036CbD53842c5426634e7929541eC2318f3dCF7e\",\n", |
| 1245 | + " \"extra\": {\n", |
| 1246 | + " \"name\": \"USDC\",\n", |
| 1247 | + " \"version\": \"2\"\n", |
| 1248 | + " }\n", |
| 1249 | + " }\n", |
| 1250 | + " ],\n", |
| 1251 | + " \"error\": \"X-PAYMENT header is required\",\n", |
| 1252 | + " \"x402Version\": 1\n", |
| 1253 | + "}\n", |
| 1254 | + "\n", |
| 1255 | + "r = fs.pay_x402_offer(x402_offer, chain=\"base-sepolia\")\n", |
| 1256 | + "r.status_code, r.json()" |
| 1257 | + ] |
| 1258 | + }, |
| 1259 | + { |
| 1260 | + "cell_type": "markdown", |
| 1261 | + "metadata": {}, |
| 1262 | + "source": [ |
| 1263 | + "### Pay X402 Link" |
| 1264 | + ] |
| 1265 | + }, |
| 1266 | + { |
| 1267 | + "cell_type": "code", |
| 1268 | + "execution_count": null, |
| 1269 | + "metadata": {}, |
| 1270 | + "outputs": [], |
| 1271 | + "source": [ |
| 1272 | + "#| export\n", |
| 1273 | + "\n", |
| 1274 | + "@patch\n", |
| 1275 | + "def pay_x402_link(self:Fewsats,\n", |
| 1276 | + " url:str, # URL to purchase from\n", |
| 1277 | + " method:str = \"GET\", # HTTP method to use\n", |
| 1278 | + " body:Dict[str, Any] = None, # Optional request body\n", |
| 1279 | + " headers:Dict[str, str] = None, # Optional request headers\n", |
| 1280 | + " chain:str = \"base\", # Blockchain chain to use\n", |
| 1281 | + " ) -> dict:\n", |
| 1282 | + " \"\"\"Creates a purchase from an external URL that requires x402 payment.\n", |
| 1283 | + " \n", |
| 1284 | + " Args:\n", |
| 1285 | + " url: The URL to purchase from\n", |
| 1286 | + " method: HTTP method to use (default: \"GET\")\n", |
| 1287 | + " body: Optional request body\n", |
| 1288 | + " headers: Optional request headers\n", |
| 1289 | + " chain: Blockchain chain to use (default: \"base\")\n", |
| 1290 | + " \n", |
| 1291 | + " Returns:\n", |
| 1292 | + " The response from the target URL after successful payment\n", |
| 1293 | + " \"\"\"\n", |
| 1294 | + " data = {\n", |
| 1295 | + " \"url\": url,\n", |
| 1296 | + " \"method\": method,\n", |
| 1297 | + " \"chain\": chain\n", |
| 1298 | + " }\n", |
| 1299 | + " \n", |
| 1300 | + " if body is not None:\n", |
| 1301 | + " data[\"body\"] = body\n", |
| 1302 | + " \n", |
| 1303 | + " if headers is not None:\n", |
| 1304 | + " data[\"headers\"] = headers\n", |
| 1305 | + " \n", |
| 1306 | + " return self._request(\"POST\", \"v0/x402/purchases/from-link\", json=data)" |
| 1307 | + ] |
| 1308 | + }, |
| 1309 | + { |
| 1310 | + "cell_type": "code", |
| 1311 | + "execution_count": null, |
| 1312 | + "metadata": {}, |
| 1313 | + "outputs": [ |
| 1314 | + { |
| 1315 | + "data": { |
| 1316 | + "text/plain": [ |
| 1317 | + "(400, {'detail': 'Redirecting...\\n'})" |
| 1318 | + ] |
| 1319 | + }, |
| 1320 | + "execution_count": 25, |
| 1321 | + "metadata": {}, |
| 1322 | + "output_type": "execute_result" |
| 1323 | + } |
| 1324 | + ], |
| 1325 | + "source": [ |
| 1326 | + "x402_link = \"https://proxy402.com/KQzW9kfi3Z\"\n", |
| 1327 | + "r = fs.pay_x402_link(x402_link, chain=\"base-sepolia\")\n", |
| 1328 | + "r.status_code, r.json()" |
| 1329 | + ] |
| 1330 | + }, |
1166 | 1331 | { |
1167 | 1332 | "cell_type": "markdown", |
1168 | 1333 | "metadata": {}, |
|
0 commit comments