Project import generated by Copybara.

GitOrigin-RevId: d9e9e3fb4e31372ec1fb43b178994ca78fa8fe70
diff --git a/static_src/prpc.js b/static_src/prpc.js
new file mode 100644
index 0000000..5b36c7a
--- /dev/null
+++ b/static_src/prpc.js
@@ -0,0 +1,67 @@
+// Copyright 2019 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+import '@chopsui/prpc-client/prpc-client.js';
+
+/**
+ * @fileoverview pRPC-related helper functions.
+ */
+export default class AutoRefreshPrpcClient {
+  constructor(token, tokenExpiresSec) {
+    this.token = token;
+    this.tokenExpiresSec = tokenExpiresSec;
+    this.prpcClient = new window.chops.rpc.PrpcClient({
+      insecure: Boolean(location.hostname === 'localhost'),
+      fetchImpl: (url, options) => {
+        options.credentials = 'same-origin';
+        return fetch(url, options);
+      },
+    });
+  }
+
+  /**
+   * Refresh the XSRF token if necessary.
+   * TODO(ehmaldonado): Figure out how to handle failures to refresh tokens.
+   * Maybe fire an event that a root page handler could use to show a message.
+   * @async
+   */
+  async ensureTokenIsValid() {
+    if (AutoRefreshPrpcClient.isTokenExpired(this.tokenExpiresSec)) {
+      const headers = {'X-Xsrf-Token': this.token};
+      const message = {
+        token: this.token,
+        tokenPath: 'xhr',
+      };
+      const freshToken = await this.prpcClient.call(
+          'monorail.Sitewide', 'RefreshToken', message, headers);
+      this.token = freshToken.token;
+      this.tokenExpiresSec = freshToken.tokenExpiresSec;
+    }
+  }
+
+  /**
+   * Sends a pRPC request. Adds this.token to the request message after making
+   * sure it is fresh.
+   * @param {string} service Full service name, including package name.
+   * @param {string} method Service method name.
+   * @param {Object} message The protobuf message to send.
+   * @return {Object} The pRPC API response.
+   */
+  call(service, method, message) {
+    return this.ensureTokenIsValid().then(() => {
+      const headers = {'X-Xsrf-Token': this.token};
+      return this.prpcClient.call(service, method, message, headers);
+    });
+  }
+
+  /**
+   * Check if the token is expired.
+   * @param {number} tokenExpiresSec: the expiration time of the token.
+   * @return {boolean} Whether the token is expired.
+   */
+  static isTokenExpired(tokenExpiresSec) {
+    const tokenExpiresDate = new Date(tokenExpiresSec * 1000);
+    return tokenExpiresDate < new Date();
+  }
+}