@tari-project/tarijs 0.4.0 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (120) hide show
  1. package/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
  2. package/.github/PULL_REQUEST_TEMPLATE.md +27 -0
  3. package/.github/dependabot.yml +8 -0
  4. package/.github/workflows/ci.yml +25 -0
  5. package/.github/workflows/npm_publish.yml +26 -0
  6. package/.github/workflows/pr_signed_commits_check.yml +19 -0
  7. package/.github/workflows/pr_title.yml +30 -0
  8. package/.moon/toolchain.yml +6 -0
  9. package/.moon/workspace.yml +32 -0
  10. package/.prettierrc +12 -0
  11. package/.prototools +9 -0
  12. package/CODEOWNERS +3 -0
  13. package/README.md +47 -0
  14. package/TODO.md +12 -0
  15. package/package.json +4 -28
  16. package/packages/builders/moon.yml +55 -0
  17. package/packages/builders/package.json +30 -0
  18. package/packages/builders/src/helpers/index.ts +2 -0
  19. package/packages/builders/src/helpers/submitTransaction.ts +97 -0
  20. package/packages/builders/src/helpers/workspace.ts +32 -0
  21. package/packages/builders/src/index.ts +9 -0
  22. package/packages/builders/src/transaction/TransactionBuilder.ts +276 -0
  23. package/packages/builders/src/transaction/TransactionRequest.ts +93 -0
  24. package/packages/builders/src/transaction/index.ts +2 -0
  25. package/packages/builders/tsconfig.json +24 -0
  26. package/packages/metamask_provider/moon.yml +55 -0
  27. package/packages/metamask_provider/package.json +30 -0
  28. package/packages/metamask_provider/src/index.ts +232 -0
  29. package/packages/metamask_provider/src/utils.ts +86 -0
  30. package/packages/metamask_provider/tsconfig.json +21 -0
  31. package/packages/tari_permissions/moon.yml +55 -0
  32. package/packages/tari_permissions/package.json +26 -0
  33. package/packages/tari_permissions/src/index.ts +1 -0
  34. package/packages/tari_permissions/src/tari_permissions.ts +312 -0
  35. package/packages/tari_permissions/tsconfig.json +15 -0
  36. package/packages/tari_provider/moon.yml +55 -0
  37. package/packages/tari_provider/package.json +27 -0
  38. package/packages/tari_provider/src/TariProvider.ts +35 -0
  39. package/packages/tari_provider/src/index.ts +3 -0
  40. package/packages/tari_provider/src/types.ts +82 -0
  41. package/packages/tari_provider/tsconfig.json +11 -0
  42. package/packages/tari_universe/moon.yml +55 -0
  43. package/packages/tari_universe/package.json +31 -0
  44. package/packages/tari_universe/src/index.ts +3 -0
  45. package/packages/tari_universe/src/provider.ts +135 -0
  46. package/packages/tari_universe/src/types.ts +33 -0
  47. package/packages/tari_universe/src/utils.ts +23 -0
  48. package/packages/tari_universe/tsconfig.json +24 -0
  49. package/packages/tarijs/integration-tests/.env +1 -0
  50. package/packages/tarijs/integration-tests/wallet_daemon/json_rpc_provider.spec.ts +191 -0
  51. package/packages/tarijs/moon.yml +63 -0
  52. package/packages/tarijs/package.json +39 -0
  53. package/packages/tarijs/src/index.ts +69 -0
  54. package/packages/tarijs/src/network.ts +8 -0
  55. package/packages/tarijs/src/templates/Account.ts +98 -0
  56. package/packages/tarijs/src/templates/Pool.ts +42 -0
  57. package/packages/tarijs/src/templates/Tariswap.ts +101 -0
  58. package/packages/tarijs/src/templates/TemplateFactory.ts +22 -0
  59. package/packages/tarijs/src/templates/TestFaucet.ts +72 -0
  60. package/{dist/utils.js → packages/tarijs/src/utils.ts} +4 -3
  61. package/packages/tarijs/tsconfig.json +39 -0
  62. package/packages/tarijs/vitest.config.ts +9 -0
  63. package/packages/tarijs_types/moon.yml +55 -0
  64. package/packages/tarijs_types/package.json +27 -0
  65. package/packages/tarijs_types/src/Amount.ts +113 -0
  66. package/packages/tarijs_types/src/Arg.ts +3 -0
  67. package/packages/tarijs_types/src/ComponentAddress.ts +3 -0
  68. package/packages/tarijs_types/src/ConfidentialClaim.ts +9 -0
  69. package/packages/tarijs_types/src/ConfidentialOutput.ts +9 -0
  70. package/packages/tarijs_types/src/ConfidentialOutputStatement.ts +10 -0
  71. package/packages/tarijs_types/src/ConfidentialStatement.ts +9 -0
  72. package/packages/tarijs_types/src/ConfidentialWithdrawProof.ts +8 -0
  73. package/packages/tarijs_types/src/ElgamalVerifiableBalance.ts +4 -0
  74. package/packages/tarijs_types/src/Epoch.ts +3 -0
  75. package/packages/tarijs_types/src/FinalizeResult.ts +17 -0
  76. package/packages/tarijs_types/src/Instruction.ts +29 -0
  77. package/packages/tarijs_types/src/ResourceAddress.ts +3 -0
  78. package/packages/tarijs_types/src/SubstateDiff.ts +9 -0
  79. package/packages/tarijs_types/src/SubstateRequirement.ts +6 -0
  80. package/packages/tarijs_types/src/TemplateAddress.ts +3 -0
  81. package/packages/tarijs_types/src/Transaction.ts +16 -0
  82. package/packages/tarijs_types/src/TransactionId.ts +4 -0
  83. package/packages/tarijs_types/src/TransactionResult.ts +26 -0
  84. package/packages/tarijs_types/src/TransactionSignature.ts +4 -0
  85. package/packages/tarijs_types/src/UnsignedTransaction.ts +15 -0
  86. package/packages/tarijs_types/src/VersionedSubstateId.ts +6 -0
  87. package/packages/tarijs_types/src/ViewableBalanceProof.ts +12 -0
  88. package/packages/tarijs_types/src/Workspace.ts +3 -0
  89. package/packages/tarijs_types/src/index.ts +25 -0
  90. package/packages/tarijs_types/tsconfig.json +15 -0
  91. package/packages/wallet_daemon/moon.yml +55 -0
  92. package/packages/wallet_daemon/package.json +29 -0
  93. package/packages/wallet_daemon/src/index.ts +5 -0
  94. package/packages/wallet_daemon/src/provider.ts +263 -0
  95. package/packages/wallet_daemon/src/webrtc.ts +229 -0
  96. package/packages/wallet_daemon/src/webrtc_transport.ts +27 -0
  97. package/packages/wallet_daemon/tsconfig.json +21 -0
  98. package/packages/walletconnect/moon.yml +55 -0
  99. package/packages/walletconnect/package.json +32 -0
  100. package/packages/walletconnect/src/index.ts +274 -0
  101. package/packages/walletconnect/tsconfig.json +21 -0
  102. package/pnpm-workspace.yaml +14 -0
  103. package/tsconfig.json +42 -0
  104. package/dist/index.d.ts +0 -14
  105. package/dist/index.js +0 -13
  106. package/dist/network.d.ts +0 -8
  107. package/dist/network.js +0 -9
  108. package/dist/templates/Account.d.ts +0 -65
  109. package/dist/templates/Account.js +0 -31
  110. package/dist/templates/Pool.d.ts +0 -29
  111. package/dist/templates/Pool.js +0 -20
  112. package/dist/templates/Tariswap.d.ts +0 -64
  113. package/dist/templates/Tariswap.js +0 -36
  114. package/dist/templates/TemplateFactory.d.ts +0 -9
  115. package/dist/templates/TemplateFactory.js +0 -18
  116. package/dist/templates/TestFaucet.d.ts +0 -49
  117. package/dist/templates/TestFaucet.js +0 -31
  118. package/dist/templates/index.js +0 -5
  119. package/dist/utils.d.ts +0 -2
  120. /package/{dist/templates/index.d.ts → packages/tarijs/src/templates/index.ts} +0 -0
@@ -0,0 +1,229 @@
1
+ import { TariPermissions } from "@tari-project/tari-permissions";
2
+ import { transports } from "@tari-project/wallet_jrpc_client";
3
+
4
+ class SignaligServer {
5
+ private _token?: string;
6
+ private _server_url: string;
7
+
8
+ constructor(server_url: string | undefined) {
9
+ console.log(server_url);
10
+ if (server_url !== undefined) {
11
+ this._server_url = server_url;
12
+ } else {
13
+ this._server_url = "http://localhost:9100";
14
+ }
15
+ }
16
+
17
+ async initToken(permissions: TariPermissions) {
18
+ this._token = await this.authLogin(permissions);
19
+ }
20
+
21
+ public get token() {
22
+ return this._token;
23
+ }
24
+
25
+ private async jsonRpc(method: string, token?: string, params?: any) {
26
+ console.log("jsonRpc", method, token, params);
27
+ let id = 0;
28
+ id += 1;
29
+ let address = this._server_url;
30
+ let headers: { [key: string]: string } = { "Content-Type": "application/json" };
31
+ if (token) {
32
+ headers["Authorization"] = `Bearer ${token}`;
33
+ }
34
+ let response = await fetch(address, {
35
+ method: "POST",
36
+ body: JSON.stringify({
37
+ method: method,
38
+ jsonrpc: "2.0",
39
+ id: id,
40
+ params: params || {},
41
+ }),
42
+ headers: headers,
43
+ });
44
+ let json = await response.json();
45
+ if (json.error) {
46
+ throw json.error;
47
+ }
48
+ return json.result;
49
+ }
50
+
51
+ private async authLogin(permissions: TariPermissions) {
52
+ return await this.jsonRpc("auth.login", undefined, permissions);
53
+ }
54
+
55
+ async storeIceCandidate(ice_candidate: RTCIceCandidate) {
56
+ return await this.jsonRpc("add.offer_ice_candidate", this._token, ice_candidate);
57
+ }
58
+
59
+ async storeOffer(offer: RTCSessionDescriptionInit) {
60
+ return await this.jsonRpc("add.offer", this._token, offer.sdp);
61
+ }
62
+
63
+ async getAnswer() {
64
+ return await this.jsonRpc("get.answer", this._token);
65
+ }
66
+
67
+ async getIceCandidates() {
68
+ return await this.jsonRpc("get.answer_ice_candidates", this._token);
69
+ }
70
+ }
71
+
72
+ export class TariConnection {
73
+ private _peerConnection: RTCPeerConnection;
74
+ private _dataChannel: RTCDataChannel;
75
+ private _signalingServer: SignaligServer;
76
+ private _callbacks: { [key: string]: any[] };
77
+ private _offer?: RTCSessionDescriptionInit;
78
+ private _walletToken: string | undefined;
79
+ // This is public so that user can directly set the onopen callback that will be called once the data channel is open.
80
+ public onopen: (() => void) | undefined;
81
+ public onConnection: ((conn: TariConnection) => void) | undefined;
82
+
83
+ constructor(signalig_server_url?: string, config?: RTCConfiguration) {
84
+ this._peerConnection = new RTCPeerConnection(config || this.config());
85
+ this._dataChannel = this._peerConnection.createDataChannel("tari-data");
86
+ this._signalingServer = new SignaligServer(signalig_server_url);
87
+ this._callbacks = {};
88
+ }
89
+
90
+ public get token() {
91
+ if (this._walletToken) {
92
+ return this._walletToken;
93
+ }
94
+ return this._signalingServer.token;
95
+ }
96
+
97
+ async init(permissions: TariPermissions, onConnection: ((conn: TariConnection) => void) | undefined) {
98
+ this.onConnection = onConnection;
99
+ await this._signalingServer.initToken(permissions);
100
+ // Setup our receiving end
101
+ this._dataChannel.onmessage = (message) => {
102
+ let response = JSON.parse(message.data);
103
+ console.log("response", response);
104
+
105
+ if (!this._callbacks[response.id]) {
106
+ console.error("No callback found for id", response.id);
107
+ return;
108
+ }
109
+ // The response should contain id, to identify the Promise.resolve, that is waiting for this result
110
+ let [resolve, reject] = this._callbacks[response.id];
111
+ delete this._callbacks[response.id];
112
+ if (response.payload?.error) {
113
+ reject(new Error(response.payload.error));
114
+ } else {
115
+ resolve(response.payload);
116
+ }
117
+ };
118
+ this._dataChannel.onopen = () => {
119
+ // This should be removed before the release, but it's good for debugging.
120
+ console.log("Data channel is open!");
121
+
122
+ this.sendMessage({ id: 0, jsonrpc: "2.0", method: "get.token", params: {} }, this._signalingServer.token)
123
+ .then((walletToken: unknown) => {
124
+ if (typeof walletToken !== "string") {
125
+ throw Error("Received invalid JWT from wallet daemon");
126
+ }
127
+
128
+ console.log("Wallet JWT received: ", walletToken);
129
+ this._walletToken = walletToken;
130
+
131
+ if (this.onConnection) {
132
+ this.onConnection(this);
133
+ }
134
+ });
135
+ };
136
+ this._peerConnection.onicecandidate = (event) => {
137
+ console.log("event", event);
138
+ if (event?.candidate) {
139
+ console.log("ICE ", event.candidate);
140
+ console.log("ICE ", typeof event.candidate);
141
+ // Store the ice candidates, so the other end can add them
142
+ this._signalingServer.storeIceCandidate(event.candidate).then((resp) => {
143
+ // This should be removed before the release, but it's good for debugging.
144
+ console.log("Candidate stored", resp);
145
+ });
146
+ }
147
+ };
148
+ // Create offer
149
+ this._offer = await this._peerConnection.createOffer();
150
+ // Set the offer as our local sdp, at this point it will start getting the ice candidates
151
+ this._peerConnection.setLocalDescription(this._offer);
152
+ // Store the offer so the other end can set it as a remote sdp
153
+ this._signalingServer.storeOffer(this._offer).then((resp) => {
154
+ // This should be removed before the release, but it's good for debugging.
155
+ console.log("Offer stored", resp);
156
+ });
157
+ await this.signalingServerPolling();
158
+ }
159
+
160
+ private async setAnswer() {
161
+ // This is called once the other end got the offer and ices and created and store an answer and its ice candidates
162
+ // We get its answer sdp
163
+ let sdp = await this._signalingServer.getAnswer();
164
+
165
+ // And its ice candidates
166
+ let iceCandidates = await this._signalingServer.getIceCandidates();
167
+
168
+ // For us the answer is remote sdp
169
+ let answer = new RTCSessionDescription({ sdp, type: "answer" });
170
+ this._peerConnection.setRemoteDescription(answer);
171
+
172
+ // We add all the ice candidates to connect, the other end is doing the same with our ice candidates
173
+ for (const iceCandidate of iceCandidates) {
174
+ this._peerConnection.addIceCandidate(iceCandidate);
175
+ }
176
+ }
177
+
178
+ private async signalingServerPolling() {
179
+ // no need to keep retrying if we are already connected to the wallet
180
+ if (this._peerConnection.connectionState === "connected") {
181
+ return;
182
+ }
183
+
184
+ try {
185
+ await this.setAnswer();
186
+ } catch (error) {
187
+ // we don't need to do anything on error, as the execution will be retried later
188
+ console.error(error);
189
+ }
190
+
191
+ // try again later
192
+ setTimeout(async () => {
193
+ await this.signalingServerPolling();
194
+ }, 2000);
195
+ }
196
+
197
+ public isConnected() {
198
+ return this._dataChannel.readyState === "open";
199
+ }
200
+
201
+ // If the last parameter has timeout property e.g. {timeout:1000}, it set the timeout for this call.
202
+ async sendMessage<T>(request: transports.RpcRequest, token: string | undefined, timeout_secs: number | null = null): Promise<T> {
203
+ if (!this.isConnected) {
204
+ throw new Error("WALLET_DAEMON_NOT_CONNECTED");
205
+ }
206
+
207
+ // This should be removed before the release, but it's good for debugging.
208
+ console.log(request, "timeout", timeout_secs);
209
+ return new Promise((resolve, reject) => {
210
+ // We store the resolve callback for this request,
211
+ // so once the data channel receives a response we know where to return the data
212
+ this._callbacks[request.id] = [resolve, reject];
213
+ if (timeout_secs) {
214
+ // If the user set a timeout which set it here so the promise will be rejected if not fulfilled in time.
215
+ setTimeout(() => {
216
+ delete this._callbacks[request.id];
217
+ reject(new Error("Timeout"));
218
+ }, timeout_secs * 1000);
219
+ }
220
+ // Make the actual call to the wallet daemon
221
+ this._dataChannel.send(JSON.stringify({ token, ...request }));
222
+ });
223
+ }
224
+
225
+ // This is our default config, use can set their own stun/turn server in the constructor.
226
+ private config() {
227
+ return { iceServers: [{ urls: "stun:stun.l.google.com:19302" }] };
228
+ }
229
+ }
@@ -0,0 +1,27 @@
1
+ import {transports} from "@tari-project/wallet_jrpc_client";
2
+ import {TariConnection} from "./webrtc";
3
+
4
+ export class WebRtcRpcTransport implements transports.RpcTransport {
5
+ connection: TariConnection;
6
+
7
+ constructor(connection: TariConnection) {
8
+ this.connection = connection;
9
+ }
10
+
11
+ static new(connection: TariConnection) {
12
+ return new WebRtcRpcTransport(connection);
13
+ }
14
+
15
+ token(): string | undefined {
16
+ return this.connection.token;
17
+ }
18
+
19
+ isConnected(): boolean {
20
+ return this.connection.isConnected();
21
+ }
22
+
23
+ sendRequest<T>(data: transports.RpcRequest, options: transports.RpcTransportOptions): Promise<T> {
24
+ return this.connection.sendMessage<T>(data, options.token);
25
+ }
26
+ }
27
+
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "ES2020",
5
+ "target": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "outDir": "./dist",
8
+ "rootDir": "./src"
9
+ },
10
+ "include": [
11
+ "src/**/*"
12
+ ],
13
+ "references": [
14
+ {
15
+ "path": "../tari_permissions"
16
+ },
17
+ {
18
+ "path": "../tari_provider"
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,55 @@
1
+ language: "typescript"
2
+ platform: "node"
3
+ type: "library"
4
+
5
+ fileGroups:
6
+ configs:
7
+ - "tsconfig.json"
8
+ - "package.json"
9
+ - "eslint.config.ts"
10
+ sources:
11
+ - "src/**/*"
12
+ tests:
13
+ - "integration-tests/**/*"
14
+
15
+ tasks:
16
+ build:
17
+ command: "pnpm run build"
18
+ inputs:
19
+ - "@files(sources)"
20
+ - "@files(configs)"
21
+ outputs:
22
+ - "dist"
23
+ format:
24
+ command: "pnpm run format"
25
+ inputs:
26
+ - "@files(sources)"
27
+ - "@files(configs)"
28
+ - "@files(tests)"
29
+ options:
30
+ runInCI: false
31
+ lint:
32
+ command: "pnpm run lint:fix"
33
+ inputs:
34
+ - "@files(sources)"
35
+ - "@files(configs)"
36
+ - "@files(tests)"
37
+ options:
38
+ runInCI: false
39
+ deps:
40
+ - "build"
41
+
42
+ lintCheck:
43
+ command: "pnpm run lint"
44
+ inputs:
45
+ - "@files(sources)"
46
+ - "@files(configs)"
47
+ - "@files(tests)"
48
+ deps:
49
+ - "build"
50
+ formatCheck:
51
+ command: "pnpm run format:check"
52
+ inputs:
53
+ - "@files(sources)"
54
+ - "@files(configs)"
55
+ - "@files(tests)"
@@ -0,0 +1,32 @@
1
+ {
2
+ "name": "@tari-project/wallet-connect-provider",
3
+ "version": "0.4.0",
4
+ "description": "",
5
+ "type": "module",
6
+ "publishConfig": {
7
+ "access": "public"
8
+ },
9
+ "scripts": {
10
+ "build": "tsc -b"
11
+ },
12
+ "keywords": [],
13
+ "author": "",
14
+ "license": "ISC",
15
+ "dependencies": {
16
+ "@tari-project/tari-provider": "workspace:^",
17
+ "@tari-project/tarijs-builders": "workspace:^",
18
+ "@tari-project/typescript-bindings": "catalog:",
19
+ "@tari-project/wallet_jrpc_client": "catalog:",
20
+ "@walletconnect/modal": "catalog:",
21
+ "@walletconnect/universal-provider": "catalog:"
22
+ },
23
+ "devDependencies": {
24
+ "@types/node": "catalog:",
25
+ "typescript": "catalog:"
26
+ },
27
+ "files": [
28
+ "/dist"
29
+ ],
30
+ "main": "dist/index.js",
31
+ "types": "dist/index.d.ts"
32
+ }
@@ -0,0 +1,274 @@
1
+ import {
2
+ TariProvider, SubmitTransactionRequest,
3
+ TransactionResult,
4
+ SubmitTransactionResponse,
5
+ VaultBalances, TemplateDefinition, Substate,
6
+ Account,
7
+ ListSubstatesResponse,
8
+ } from "@tari-project/tari-provider";
9
+ import {
10
+ TransactionStatus,
11
+ } from "@tari-project/tarijs-builders";
12
+ import UniversalProvider from "@walletconnect/universal-provider";
13
+ import { WalletConnectModal } from "@walletconnect/modal";
14
+ import {
15
+ Instruction,
16
+ KeyBranch,
17
+ stringToSubstateId,
18
+ substateIdToString,
19
+ SubstateType,
20
+ TransactionSubmitRequest,
21
+ } from "@tari-project/wallet_jrpc_client";
22
+
23
+ const walletConnectParams = {
24
+ requiredNamespaces: {
25
+ tari: {
26
+ methods: [
27
+ "tari_getSubstate",
28
+ "tari_getDefaultAccount",
29
+ "tari_getAccountBalances",
30
+ "tari_submitTransaction",
31
+ "tari_getTransactionResult",
32
+ "tari_getTemplate",
33
+ "tari_createKey",
34
+ "tari_viewConfidentialVaultBalance",
35
+ "tari_createFreeTestCoins",
36
+ "tari_listSubstates",
37
+ ],
38
+ chains: [
39
+ "tari:devnet",
40
+ ],
41
+ events: ["chainChanged\", \"accountsChanged"],
42
+ },
43
+ },
44
+ };
45
+
46
+ export class WalletConnectTariProvider implements TariProvider {
47
+ public providerName = "WalletConnect";
48
+ projectId: string;
49
+ wcProvider: UniversalProvider | null;
50
+ wcSession: any | null;
51
+
52
+ constructor(projectId: string) {
53
+ this.projectId = projectId;
54
+ this.wcProvider = null;
55
+ this.wcSession = null;
56
+ }
57
+
58
+ async connect(): Promise<void> {
59
+ if (this.wcProvider && this.wcSession)
60
+ return;
61
+
62
+ // initialize WalletConnect
63
+ const projectId = this.projectId;
64
+ this.wcProvider = await UniversalProvider.init({
65
+ projectId,
66
+ // TODO: parameterize the relay URL
67
+ relayUrl: "wss://relay.walletconnect.com",
68
+ });
69
+
70
+ // open UI modal with the connection URI
71
+ const { uri, approval } = await this.wcProvider.client.connect(walletConnectParams);
72
+ const walletConnectModal = new WalletConnectModal({
73
+ projectId,
74
+ });
75
+ if (uri) {
76
+ walletConnectModal.openModal({ uri });
77
+ }
78
+
79
+ // wait for the wallet to approve the connection
80
+ console.log("waiting for session approval from the wallet app");
81
+ const session = await approval();
82
+ walletConnectModal.closeModal();
83
+
84
+ // at this point session is open
85
+ console.log("session approved by the wallet");
86
+ this.wcSession = session;
87
+ }
88
+
89
+ private async sendRequest(method: string, params: object): Promise<any> {
90
+ if (!this.wcProvider) {
91
+ throw "WalletConnect provider not initialized";
92
+ }
93
+
94
+ if (!this.wcSession) {
95
+ throw "WalletConnect session not initialized";
96
+ }
97
+
98
+ const requestResult = await this.wcProvider.client.request({
99
+ topic: this.wcSession.topic,
100
+ chainId: "tari:devnet",
101
+ request: {
102
+ method,
103
+ params,
104
+ },
105
+ });
106
+
107
+ console.log({ requestResult });
108
+
109
+ return requestResult;
110
+ }
111
+
112
+
113
+ isConnected(): boolean {
114
+ // TODO: check status in the session
115
+ return this.wcSession !== null;
116
+ }
117
+
118
+ async getAccount(): Promise<Account> {
119
+ const { account, public_key } = await this.sendRequest("tari_getDefaultAccount", {});
120
+ const { balances } = await this.sendRequest(
121
+ "tari_getAccountBalances",
122
+ {
123
+ account: { ComponentAddress: account.address }, refresh: false,
124
+ });
125
+
126
+ return {
127
+ account_id: account.key_index,
128
+ address: account.address,
129
+ public_key,
130
+ // TODO: should be vaults not resources
131
+ resources: balances.map((b: any) => ({
132
+ type: b.resource_type,
133
+ resource_address: b.resource_address,
134
+ balance: b.balance + b.confidential_balance,
135
+ vault_id: (typeof (b.vault_address) === "object" && "Vault" in b.vault_address) ? b.vault_address.Vault : b.vault_address,
136
+ token_symbol: b.token_symbol,
137
+ })),
138
+ };
139
+ }
140
+
141
+ async getSubstate(substate_address: string): Promise<Substate> {
142
+ const method = "tari_getSubstate";
143
+ const params = { substate_id: substate_address };
144
+ const { value, record } = await this.sendRequest(method, params);
145
+ return {
146
+ value,
147
+ address: {
148
+ substate_id: record.substate_id,
149
+ version: record.version,
150
+ },
151
+ };
152
+ }
153
+
154
+ public async listSubstates(filter_by_template: string | null, filter_by_type: SubstateType | null, limit: number | null, offset: number | null): Promise<ListSubstatesResponse> {
155
+ const method = "tari_listSubstates";
156
+ const params = {
157
+ filter_by_template,
158
+ filter_by_type,
159
+ limit,
160
+ offset,
161
+ };
162
+ const res = await this.sendRequest(method, params);
163
+ const substates = res.substates.map((s: any) => ({
164
+ substate_id: substateIdToString(s.substate_id),
165
+ module_name: s.module_name,
166
+ version: s.version,
167
+ template_address: s.template_address,
168
+ }));
169
+
170
+ return { substates };
171
+ }
172
+
173
+ public async createFreeTestCoins(): Promise<Account> {
174
+ const method = "tari_createFreeTestCoins";
175
+ const params = {
176
+ account: { Name: "template_web" },
177
+ amount: 1000000,
178
+ max_fee: null,
179
+ key_id: 0,
180
+ };
181
+ const res = await this.sendRequest(method, params);
182
+ return {
183
+ account_id: res.account.key_index,
184
+ address: (res.account.address as { Component: string }).Component,
185
+ public_key: res.public_key,
186
+ resources: [],
187
+ };
188
+ }
189
+
190
+ async submitTransaction(req: SubmitTransactionRequest): Promise<SubmitTransactionResponse> {
191
+ const method = "tari_submitTransaction";
192
+ const params: TransactionSubmitRequest = {
193
+ transaction: {
194
+ V1: {
195
+ network: req.network,
196
+ fee_instructions: req.fee_instructions as Instruction[],
197
+ instructions: req.instructions as Instruction[],
198
+ inputs: req.required_substates.map((s) => ({
199
+ // TODO: Hmm The bindings want a SubstateId object, but the wallet only wants a string. Any is used to skip type checking here
200
+ substate_id: s.substate_id as any,
201
+ version: s.version ?? null,
202
+ })),
203
+ min_epoch: null,
204
+ max_epoch: null,
205
+ is_seal_signer_authorized: req.is_seal_signer_authorized,
206
+ },
207
+ },
208
+ signing_key_index: req.account_id,
209
+ autofill_inputs: [],
210
+ detect_inputs: true,
211
+ proof_ids: [],
212
+ detect_inputs_use_unversioned: req.detect_inputs_use_unversioned,
213
+ };
214
+
215
+ const res = await this.sendRequest(method, params);
216
+
217
+ return { transaction_id: res.transaction_id };
218
+ }
219
+
220
+ async getTransactionResult(transactionId: string): Promise<TransactionResult> {
221
+ const res = await this.sendRequest("tari_getTransactionResult", { transaction_id: transactionId });
222
+
223
+ return {
224
+ transaction_id: transactionId,
225
+ status: convertStringToTransactionStatus(res.status),
226
+ result: res.result,
227
+ };
228
+ }
229
+
230
+ async getTemplateDefinition(template_address: string): Promise<TemplateDefinition> {
231
+ let resp = await this.sendRequest("tari_getTemplate", { template_address });
232
+ return resp.template_definition as TemplateDefinition;
233
+ }
234
+
235
+ async getPublicKey(branch: string, index: number): Promise<string> {
236
+ const res = await this.sendRequest("tari_createKey", { branch: branch as KeyBranch, specific_index: index });
237
+ return res.public_key;
238
+ }
239
+
240
+ async getConfidentialVaultBalances(viewKeyId: number, vaultId: string, min: number | null, max: number | null): Promise<VaultBalances> {
241
+ const method = "tari_viewConfidentialVaultBalance";
242
+ const params = {
243
+ view_key_id: viewKeyId,
244
+ vault_id: vaultId,
245
+ minimum_expected_value: min,
246
+ maximum_expected_value: max,
247
+ };
248
+
249
+ const res = await this.sendRequest(method, params);
250
+ return { balances: res.balances as unknown as Map<string, number | null> };
251
+ }
252
+
253
+ }
254
+
255
+ function convertStringToTransactionStatus(status: string): TransactionStatus {
256
+ switch (status) {
257
+ case "New":
258
+ return TransactionStatus.New;
259
+ case "DryRun":
260
+ return TransactionStatus.DryRun;
261
+ case "Pending":
262
+ return TransactionStatus.Pending;
263
+ case "Accepted":
264
+ return TransactionStatus.Accepted;
265
+ case "Rejected":
266
+ return TransactionStatus.Rejected;
267
+ case "InvalidTransaction":
268
+ return TransactionStatus.InvalidTransaction;
269
+ case "OnlyFeeAccepted":
270
+ return TransactionStatus.OnlyFeeAccepted;
271
+ default:
272
+ throw new Error(`Unknown status: ${status}`);
273
+ }
274
+ }
@@ -0,0 +1,21 @@
1
+ {
2
+ "extends": "../../tsconfig.json",
3
+ "compilerOptions": {
4
+ "module": "ES2020",
5
+ "target": "ESNext",
6
+ "moduleResolution": "Bundler",
7
+ "outDir": "./dist",
8
+ "rootDir": "./src"
9
+ },
10
+ "include": [
11
+ "src/**/*"
12
+ ],
13
+ "references": [
14
+ {
15
+ "path": "../builders"
16
+ },
17
+ {
18
+ "path": "../tari_provider"
19
+ }
20
+ ]
21
+ }
@@ -0,0 +1,14 @@
1
+ packages:
2
+ - packages/*
3
+ - apps/*
4
+ - "!**/test/**"
5
+ catalog:
6
+ typescript: ^5.0.4
7
+ vitest: ^3.0.4
8
+ vite: ^6.1.0
9
+ "@types/node": ^22.13.1
10
+ "@tari-project/typescript-bindings": ^1.4.0
11
+ "@tari-project/wallet_jrpc_client": ^1.4.0
12
+ "@metamask/providers": ^18.2.0
13
+ "@walletconnect/universal-provider": ^2.13.3
14
+ "@walletconnect/modal": ^2.6.2