ソースを参照

adapt sdks (#1434)

* adapt sdks

* update the sdks to reflect bid status ups

* some js changes

* python hex fix

* update gen types

* bump versions

* fix docs

---------

Co-authored-by: ani <ani@Anirudhs-MBP.cable.rcn.com>
Co-authored-by: ani <ani@Anirudhs-MacBook-Pro.local>
Anirudh Suresh 1 年間 前
コミット
1135f00da2

+ 3 - 2
express_relay/sdk/js/package.json

@@ -1,6 +1,6 @@
 {
   "name": "@pythnetwork/express-relay-evm-js",
-  "version": "0.2.0",
+  "version": "0.2.1",
   "description": "Utilities for interacting with the express relay protocol",
   "homepage": "https://github.com/pyth-network/pyth-crosschain/tree/main/express_relay/sdk/js",
   "author": "Douro Labs",
@@ -42,10 +42,11 @@
     "ws": "^8.16.0"
   },
   "devDependencies": {
+    "@pythnetwork/pyth-evm-js": "*",
+    "@types/node": "^20.12.7",
     "@types/yargs": "^17.0.10",
     "@typescript-eslint/eslint-plugin": "^5.21.0",
     "@typescript-eslint/parser": "^5.21.0",
-    "@pythnetwork/pyth-evm-js": "*",
     "eslint": "^8.56.0",
     "jest": "^27.5.1",
     "prettier": "^2.6.2",

+ 7 - 3
express_relay/sdk/js/src/examples/simpleSearcher.ts

@@ -23,10 +23,14 @@ class SimpleSearcher {
   }
 
   async bidStatusHandler(bidStatus: BidStatusUpdate) {
+    let resultDetails = "";
+    if (bidStatus.type == "submitted") {
+      resultDetails = `, transaction ${bidStatus.result}, index ${bidStatus.index} of multicall`;
+    } else if (bidStatus.type == "lost") {
+      resultDetails = `, transaction ${bidStatus.result}`;
+    }
     console.log(
-      `Bid status for bid ${bidStatus.id}: ${bidStatus.status} ${
-        bidStatus.status == "submitted" ? bidStatus.result : ""
-      }`
+      `Bid status for bid ${bidStatus.id}: ${bidStatus.type}${resultDetails}`
     );
   }
 

+ 25 - 23
express_relay/sdk/js/src/serverTypes.d.ts

@@ -10,7 +10,7 @@ export interface paths {
      * @description Bid on a specific permission key for a specific chain.
      *
      * Your bid will be simulated and verified by the server. Depending on the outcome of the auction, a transaction
-     * containing the targetContract call will be sent to the blockchain expecting the bid amount to be paid after the call.
+     * containing the contract call will be sent to the blockchain expecting the bid amount to be paid after the call.
      */
     post: operations["bid"];
   };
@@ -58,7 +58,7 @@ export interface components {
       amount: string;
       /**
        * @description The chain id to bid on.
-       * @example sepolia
+       * @example op_sepolia
        */
       chain_id: string;
       /**
@@ -67,12 +67,12 @@ export interface components {
        */
       permission_key: string;
       /**
-       * @description Calldata for the targetContract call.
+       * @description Calldata for the contract call.
        * @example 0xdeadbeef
        */
       target_calldata: string;
       /**
-       * @description The targetContract address to call.
+       * @description The contract address to call.
        * @example 0xcA11bde05977b3631167028862bE2a173976CA11
        */
       target_contract: string;
@@ -88,20 +88,24 @@ export interface components {
     BidStatus:
       | {
           /** @enum {string} */
-          status: "pending";
+          type: "pending";
         }
       | {
           /**
-           * @description The bid won the auction and was submitted to the chain in a transaction with the given hash
-           * @example 0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3
+           * Format: int32
+           * @example 1
            */
+          index: number;
+          /** @example 0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3 */
           result: string;
           /** @enum {string} */
-          status: "submitted";
+          type: "submitted";
         }
       | {
+          /** @example 0x103d4fbd777a36311b5161f2062490f761f25b67406badb2bace62bb170aa4e3 */
+          result: string;
           /** @enum {string} */
-          status: "lost";
+          type: "lost";
         };
     BidStatusWithId: {
       bid_status: components["schemas"]["BidStatus"];
@@ -174,14 +178,14 @@ export interface components {
     /**
      * @description Opportunity parameters needed for on-chain execution
      * If a searcher signs the opportunity and have approved enough tokens to opportunity adapter,
-     * by calling this target targetContract with the given target targetCalldata and structures, they will
+     * by calling this target contract with the given target calldata and structures, they will
      * send the tokens specified in the sell_tokens field and receive the tokens specified in the buy_tokens field.
      */
     OpportunityParamsV1: {
       buy_tokens: components["schemas"]["TokenAmount"][];
       /**
        * @description The chain id where the opportunity will be executed.
-       * @example sepolia
+       * @example op_sepolia
        */
       chain_id: string;
       /**
@@ -191,17 +195,17 @@ export interface components {
       permission_key: string;
       sell_tokens: components["schemas"]["TokenAmount"][];
       /**
-       * @description The targetCallValue to send with the targetContract call.
+       * @description The value to send with the contract call.
        * @example 1
        */
       target_call_value: string;
       /**
-       * @description Calldata for the target targetContract call.
+       * @description Calldata for the target contract call.
        * @example 0xdeadbeef
        */
       target_calldata: string;
       /**
-       * @description The targetContract address to call for execution of the opportunity.
+       * @description The contract address to call for execution of the opportunity.
        * @example 0xcA11bde05977b3631167028862bE2a173976CA11
        */
       target_contract: string;
@@ -212,9 +216,8 @@ export interface components {
       version: "v1";
     }) & {
       /**
-       * Format: int64
-       * @description Creation time of the opportunity
-       * @example 1700000000
+       * @description Creation time of the opportunity (in microseconds since the Unix epoch)
+       * @example 1700000000000000
        */
       creation_time: number;
       /**
@@ -260,7 +263,7 @@ export interface components {
        */
       amount: string;
       /**
-       * @description Token targetContract address
+       * @description Token contract address
        * @example 0xC02aaA39b223FE8D0A0e5C4F27eAD9083C756Cc2
        */
       token: string;
@@ -295,9 +298,8 @@ export interface components {
           version: "v1";
         }) & {
           /**
-           * Format: int64
-           * @description Creation time of the opportunity
-           * @example 1700000000
+           * @description Creation time of the opportunity (in microseconds since the Unix epoch)
+           * @example 1700000000000000
            */
           creation_time: number;
           /**
@@ -325,7 +327,7 @@ export interface operations {
    * @description Bid on a specific permission key for a specific chain.
    *
    * Your bid will be simulated and verified by the server. Depending on the outcome of the auction, a transaction
-   * containing the targetContract call will be sent to the blockchain expecting the bid amount to be paid after the call.
+   * containing the contract call will be sent to the blockchain expecting the bid amount to be paid after the call.
    */
   bid: {
     requestBody: {
@@ -383,7 +385,7 @@ export interface operations {
   get_opportunities: {
     parameters: {
       query?: {
-        /** @example sepolia */
+        /** @example op_sepolia */
         chain_id?: string | null;
       };
     };

+ 6 - 2
express_relay/sdk/python/express_relay/client.py

@@ -322,10 +322,14 @@ class ExpressRelayClient:
                 elif msg_json.get("type") == "bid_status_update":
                     if bid_status_callback is not None:
                         id = msg_json["status"]["id"]
-                        bid_status = msg_json["status"]["bid_status"]["status"]
+                        bid_status = msg_json["status"]["bid_status"]["type"]
                         result = msg_json["status"]["bid_status"].get("result")
+                        index = msg_json["status"]["bid_status"].get("index")
                         bid_status_update = BidStatusUpdate(
-                            id=id, bid_status=BidStatus(bid_status), result=result
+                            id=id,
+                            bid_status=BidStatus(bid_status),
+                            result=result,
+                            index=index,
                         )
                         asyncio.create_task(bid_status_callback(bid_status_update))
 

+ 6 - 2
express_relay/sdk/python/express_relay/searcher/examples/simple_searcher.py

@@ -77,9 +77,13 @@ class SimpleSearcher:
         result = bid_status_update.result
 
         if bid_status == BidStatus("submitted"):
-            logger.info(f"Bid {id} has been submitted in hash {result}")
+            logger.info(
+                f"Bid {id} has been submitted in transaction {result} at index {bid_status_update.index} of the multicall"
+            )
         elif bid_status == BidStatus("lost"):
-            logger.info(f"Bid {id} was unsuccessful")
+            logger.info(
+                f"Bid {id} was unsuccessful, not included in transaction {result}"
+            )
         elif bid_status == BidStatus("pending"):
             logger.info(f"Bid {id} is pending")
         else:

+ 13 - 3
express_relay/sdk/python/express_relay/types.py

@@ -112,19 +112,29 @@ class BidStatusUpdate(BaseModel):
     Attributes:
         id: The ID of the bid.
         bid_status: The status enum, either SUBMITTED, LOST, or PENDING.
-        result: The result of the bid: a transaction hash if the status is SUBMITTED, else None.
+        result: The result of the bid: a transaction hash if the status is SUBMITTED or LOST, else None.
+        index: The index of the bid in the submitted transaction; None if the status is not SUBMITTED.
     """
 
     id: UUIDString
     bid_status: BidStatus
     result: Bytes32 | None = Field(default=None)
+    index: int | None = Field(default=None)
 
     @model_validator(mode="after")
     def check_result(self):
-        if self.bid_status == BidStatus("submitted"):
+        if self.bid_status == BidStatus("pending"):
+            assert self.result is None, "result must be None"
+        else:
             assert self.result is not None, "result must be a valid 32-byte hash"
+        return self
+
+    @model_validator(mode="after")
+    def check_index(self):
+        if self.bid_status == BidStatus("submitted"):
+            assert self.index is not None, "index must be a valid integer"
         else:
-            assert self.result is None, "result must be None"
+            assert self.index is None, "index must be None"
         return self
 
 

+ 1 - 1
express_relay/sdk/python/pyproject.toml

@@ -1,6 +1,6 @@
 [tool.poetry]
 name = "express-relay"
-version = "0.2.0"
+version = "0.2.1"
 description = "Utilities for searchers and protocols to interact with the Express Relay protocol."
 authors = ["dourolabs"]
 license = "Proprietary"

+ 32 - 0
package-lock.json

@@ -982,6 +982,7 @@
       },
       "devDependencies": {
         "@pythnetwork/pyth-evm-js": "*",
+        "@types/node": "^20.12.7",
         "@types/yargs": "^17.0.10",
         "@typescript-eslint/eslint-plugin": "^5.21.0",
         "@typescript-eslint/parser": "^5.21.0",
@@ -1349,6 +1350,15 @@
         "@sinonjs/commons": "^1.7.0"
       }
     },
+    "express_relay/sdk/js/node_modules/@types/node": {
+      "version": "20.12.7",
+      "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
+      "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
+      "dev": true,
+      "dependencies": {
+        "undici-types": "~5.26.4"
+      }
+    },
     "express_relay/sdk/js/node_modules/abitype": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.0.tgz",
@@ -53777,6 +53787,12 @@
         "node": ">=14.0"
       }
     },
+    "node_modules/undici-types": {
+      "version": "5.26.5",
+      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+      "dev": true
+    },
     "node_modules/unicode-canonical-property-names-ecmascript": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",
@@ -68257,6 +68273,7 @@
       "version": "file:express_relay/sdk/js",
       "requires": {
         "@pythnetwork/pyth-evm-js": "*",
+        "@types/node": "^20.12.7",
         "@types/yargs": "^17.0.10",
         "@typescript-eslint/eslint-plugin": "^5.21.0",
         "@typescript-eslint/parser": "^5.21.0",
@@ -68559,6 +68576,15 @@
             "@sinonjs/commons": "^1.7.0"
           }
         },
+        "@types/node": {
+          "version": "20.12.7",
+          "resolved": "https://registry.npmjs.org/@types/node/-/node-20.12.7.tgz",
+          "integrity": "sha512-wq0cICSkRLVaf3UGLMGItu/PtdY7oaXaI/RVU+xliKVOtRna3PRY57ZDfztpDL0n11vfymMUnXv8QwYCO7L1wg==",
+          "dev": true,
+          "requires": {
+            "undici-types": "~5.26.4"
+          }
+        },
         "abitype": {
           "version": "1.0.0",
           "resolved": "https://registry.npmjs.org/abitype/-/abitype-1.0.0.tgz",
@@ -104020,6 +104046,12 @@
         "@fastify/busboy": "^2.0.0"
       }
     },
+    "undici-types": {
+      "version": "5.26.5",
+      "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz",
+      "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==",
+      "dev": true
+    },
     "unicode-canonical-property-names-ecmascript": {
       "version": "2.0.0",
       "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz",