You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

Wallet.jsx 7.1KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190
  1. import React from "react";
  2. import * as _ from "lodash";
  3. import { connect, WalletConnection, keyStores, Near } from 'near-api-js';
  4. const { KeyProvisioner, ProvisionerConfig } = await import("../../../pkg/web_client");
  5. class Wallet extends React.Component {
  6. constructor(props) {
  7. super(props);
  8. this.state = {
  9. isSignedIn: false,
  10. keyStore: new keyStores.BrowserLocalStorageKeyStore(),
  11. accountId: null,
  12. walletConnection: null,
  13. nearConnection: null,
  14. timeouts: {
  15. default_ms: 7000,
  16. interaction_ms: 30_000
  17. },
  18. provisioner: null,
  19. secretKey: null,
  20. meetingId: null,
  21. participants: [],
  22. };
  23. }
  24. setStateAsync(state) {
  25. return new Promise((resolve) => {
  26. this.setState(state, resolve)
  27. });
  28. }
  29. async componentDidMount() {
  30. let keyStore = this.state.keyStore;
  31. let nearConnectionCall = async () => {
  32. let connectionConfig = {
  33. networkId: "testnet",
  34. keyStore,
  35. nodeUrl: "https://rpc.testnet.near.org",
  36. walletUrl: "https://wallet.testnet.near.org",
  37. helperUrl: "https://helper.testnet.near.org",
  38. explorerUrl: "https://explorer.testnet.near.org",
  39. };
  40. let nearConnection = await connect(connectionConfig);
  41. return nearConnection;
  42. };
  43. let nearConnection = await nearConnectionCall();
  44. let walletConnection = new WalletConnection(nearConnection, null);
  45. await this.setStateAsync({ ...this.state, keyStore, nearConnection, walletConnection, accountId: walletConnection.getAccountId() })
  46. if (this.state.walletConnection.isSignedIn()) {
  47. await this.setStateAsync({ ...this.state, isSignedIn: true });
  48. await this.handleWallet();
  49. }
  50. }
  51. async requestSignIn() {
  52. if (!this.state.walletConnection.isSignedIn()) {
  53. await this.state.walletConnection.requestSignIn(this.state.accountId, "Test App");
  54. }
  55. }
  56. async handleWallet() {
  57. let accountId = this.state.accountId;
  58. let account = await this.state.nearConnection.account(accountId);
  59. let accessKeys = await account.getAccessKeys();
  60. let keypair = await this.state.keyStore.getKey("testnet", accountId);
  61. let found = accessKeys.find(key => key.public_key == keypair.getPublicKey().toString());
  62. let config = new ProvisionerConfig("relayz-meet.testnet", "https://rpc.testnet.near.org", "https://ks.relayz.io:3000");
  63. await this.setStateAsync({
  64. ...this.state,
  65. provisioner: new KeyProvisioner(keypair.toString(), BigInt(found.access_key.nonce), accountId, config)
  66. });
  67. console.log("KeyPair: ", keypair.getPublicKey().toString());
  68. console.log("Account: ", account);
  69. }
  70. async handleMeetingStart() {
  71. let participants = this.state.participants;
  72. let provisioner = this.state.provisioner;
  73. let default_ms = this.state.timeouts.default_ms;
  74. let interaction_ms = this.state.timeouts.interaction_ms;
  75. if (participants.length > 0) {
  76. console.log("Participants: " + participants);
  77. provisioner.init_meeting(new Set(participants), default_ms)
  78. .then((meeting) => {
  79. this.props.setMeetingId(meeting.meet_id);
  80. let meetingId = meeting.meet_id;
  81. this.setState({ ...this.state, meetingId });
  82. console.log("Meeting Id:", meeting.meet_id);
  83. provisioner.send_keys(meeting.meet_id, interaction_ms)
  84. .then((secretKey) => {
  85. this.setState({ ...this.state, secretKey });
  86. this.props.setSecretKey(secretKey);
  87. console.log("Secret Key" + secretKey);
  88. })
  89. .then(() => console.log("Send keys is ok"))
  90. .catch((err) => {
  91. console.log("Error: ", err);
  92. });
  93. })
  94. .then(() => console.log("Init is ok"))
  95. .catch((err) => {
  96. console.log("Error: ", err);
  97. });
  98. }
  99. }
  100. async handleMeetingJoin() {
  101. if (this.state.meetingId.length == null) {
  102. return
  103. }
  104. let meetingId = this.state.meetingId;
  105. let provisioner = this.state.provisioner;
  106. let default_ms = this.state.timeouts.default_ms;
  107. this.props.setMeetingId(meetingId);
  108. provisioner.get_key(meetingId, default_ms).then((secretKey) => {
  109. this.props.setSecretKey(secretKey);
  110. this.setState({ ...this.state, secretKey });
  111. console.log("Secret Key" + secretKey);
  112. }).catch((err) => {
  113. console.log("Error: ", err);
  114. });
  115. }
  116. render() {
  117. return (
  118. <div className="container">
  119. <div className="moderator-part">
  120. <label>Moderator part: </label>
  121. <div className="sign-in">
  122. <label>Account: </label>
  123. <input
  124. type="text"
  125. disabled={this.state.isSignedIn}
  126. onChange={e => this.setState({ accountId: e.target.value })}
  127. defaultValue={this.state.accountId}
  128. />
  129. <button disabled={this.state.isSignedIn} onClick={() => this.requestSignIn()}>
  130. Login
  131. </button>
  132. </div>
  133. <div>
  134. <label>Init meeting with participants:</label>
  135. <input
  136. type="text"
  137. onBlur={e => this.setState({ participants: e.target.value.split(',').map((id) => id.trim()) })}
  138. />
  139. <button onClick={() => this.handleMeetingStart()}>Start Meeting</button>
  140. </div>
  141. <div>
  142. <label>
  143. Meeting ID: {this.state.meetingId}
  144. </label>
  145. </div>
  146. </div>
  147. <div className="end-user-part">
  148. <label>End-user part: </label>
  149. <div>
  150. <label>Meeting ID: </label>
  151. <input
  152. type="text" id="inp_meeting_id" name="meeting"
  153. onBlur={e => this.setState({ meetingId: e.target.value })}
  154. />
  155. <button id="join_meeting_id" onClick={() => this.handleMeetingJoin()}>Join Meeting</button>
  156. </div>
  157. <div>
  158. <label>Secret: {this.state.secretKey}</label>
  159. </div>
  160. </div>
  161. </div>
  162. );
  163. }
  164. }
  165. export default Wallet;