@tari-project/tarijs 0.4.0 → 0.4.2
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.
- package/.github/ISSUE_TEMPLATE/bug_report.md +36 -0
- package/.github/PULL_REQUEST_TEMPLATE.md +27 -0
- package/.github/dependabot.yml +8 -0
- package/.github/workflows/ci.yml +26 -0
- package/.github/workflows/documentation-deploy.yml +44 -0
- package/.github/workflows/documentation-test-deploy.yml +20 -0
- package/.github/workflows/npm_publish.yml +26 -0
- package/.github/workflows/pr_signed_commits_check.yml +19 -0
- package/.github/workflows/pr_title.yml +30 -0
- package/.moon/toolchain.yml +6 -0
- package/.moon/workspace.yml +33 -0
- package/.prettierrc +12 -0
- package/.prototools +9 -0
- package/CODEOWNERS +3 -0
- package/README.md +66 -0
- package/TODO.md +12 -0
- package/docusaurus/tari-docs/README.md +41 -0
- package/docusaurus/tari-docs/docs/index.md +16 -0
- package/docusaurus/tari-docs/docs/installation.md +27 -0
- package/docusaurus/tari-docs/docs/providers/_category_.json +8 -0
- package/docusaurus/tari-docs/docs/providers/tari-universe.md +27 -0
- package/docusaurus/tari-docs/docs/providers/wallet-connect.md +52 -0
- package/docusaurus/tari-docs/docs/providers/wallet-daemon.md +37 -0
- package/docusaurus/tari-docs/docs/wallet/_category_.json +8 -0
- package/docusaurus/tari-docs/docs/wallet/default-account.md +51 -0
- package/docusaurus/tari-docs/docs/wallet/get-substate.md +110 -0
- package/docusaurus/tari-docs/docs/wallet/list-substates.md +69 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/_category_.json +8 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/build-execute-request.md +38 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/index.md +14 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/_category_.json +8 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/call-function.md +17 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/call-method.md +17 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/fee.md +28 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/index.md +426 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/inputs.md +24 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/instruction.md +108 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/min-max-epoch.md +19 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/raw-instructions.md +16 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/save-var.md +63 -0
- package/docusaurus/tari-docs/docs/wallet/submit-transaction/transaction-builder/transaction-internals.md +20 -0
- package/docusaurus/tari-docs/docs/wallet/template-definition.md +101 -0
- package/docusaurus/tari-docs/docusaurus.config.ts +108 -0
- package/docusaurus/tari-docs/moon.yml +41 -0
- package/docusaurus/tari-docs/package.json +49 -0
- package/docusaurus/tari-docs/sidebars.ts +7 -0
- package/docusaurus/tari-docs/src/components/HomepageFeatures/index.tsx +69 -0
- package/docusaurus/tari-docs/src/components/HomepageFeatures/styles.module.css +11 -0
- package/docusaurus/tari-docs/src/css/custom.css +30 -0
- package/docusaurus/tari-docs/src/pages/index.module.css +23 -0
- package/docusaurus/tari-docs/src/pages/index.tsx +44 -0
- package/docusaurus/tari-docs/static/.nojekyll +0 -0
- package/docusaurus/tari-docs/static/img/favicon.png +0 -0
- package/docusaurus/tari-docs/static/img/meta-image.png +0 -0
- package/docusaurus/tari-docs/static/img/tari/wallet-connect-1.png +0 -0
- package/docusaurus/tari-docs/static/img/tari/wallet-connect-2.png +0 -0
- package/docusaurus/tari-docs/static/img/tari/wallet-connect-3.png +0 -0
- package/docusaurus/tari-docs/static/img/tari-logo.svg +30 -0
- package/docusaurus/tari-docs/tsconfig.json +8 -0
- package/package.json +4 -28
- package/packages/builders/moon.yml +55 -0
- package/packages/builders/package.json +30 -0
- package/packages/builders/src/helpers/index.ts +2 -0
- package/packages/builders/src/helpers/submitTransaction.ts +97 -0
- package/packages/builders/src/helpers/workspace.ts +32 -0
- package/packages/builders/src/index.ts +9 -0
- package/packages/builders/src/transaction/TransactionBuilder.ts +276 -0
- package/packages/builders/src/transaction/TransactionRequest.ts +93 -0
- package/packages/builders/src/transaction/index.ts +2 -0
- package/packages/builders/tsconfig.json +24 -0
- package/packages/metamask_provider/moon.yml +55 -0
- package/packages/metamask_provider/package.json +30 -0
- package/packages/metamask_provider/src/index.ts +232 -0
- package/packages/metamask_provider/src/utils.ts +86 -0
- package/packages/metamask_provider/tsconfig.json +21 -0
- package/packages/tari_permissions/moon.yml +55 -0
- package/packages/tari_permissions/package.json +26 -0
- package/packages/tari_permissions/src/index.ts +1 -0
- package/packages/tari_permissions/src/tari_permissions.ts +312 -0
- package/packages/tari_permissions/tsconfig.json +15 -0
- package/packages/tari_provider/moon.yml +55 -0
- package/packages/tari_provider/package.json +27 -0
- package/packages/tari_provider/src/TariProvider.ts +34 -0
- package/packages/tari_provider/src/index.ts +3 -0
- package/packages/tari_provider/src/types.ts +84 -0
- package/packages/tari_provider/tsconfig.json +11 -0
- package/packages/tari_universe/moon.yml +55 -0
- package/packages/tari_universe/package.json +31 -0
- package/packages/tari_universe/src/index.ts +3 -0
- package/packages/tari_universe/src/provider.ts +120 -0
- package/packages/tari_universe/src/types.ts +33 -0
- package/packages/tari_universe/src/utils.ts +23 -0
- package/packages/tari_universe/tsconfig.json +24 -0
- package/packages/tarijs/integration-tests/.env +1 -0
- package/packages/tarijs/integration-tests/wallet_daemon/json_rpc_provider.spec.ts +191 -0
- package/packages/tarijs/moon.yml +71 -0
- package/packages/tarijs/package.json +40 -0
- package/packages/tarijs/src/cbor.spec.ts +259 -0
- package/packages/tarijs/src/cbor.ts +114 -0
- package/packages/tarijs/src/index.ts +72 -0
- package/packages/tarijs/src/network.ts +8 -0
- package/packages/tarijs/src/templates/Account.ts +98 -0
- package/packages/tarijs/src/templates/Pool.ts +42 -0
- package/packages/tarijs/src/templates/Tariswap.ts +101 -0
- package/packages/tarijs/src/templates/TemplateFactory.ts +22 -0
- package/packages/tarijs/src/templates/TestFaucet.ts +72 -0
- package/{dist/utils.js → packages/tarijs/src/utils.ts} +4 -3
- package/packages/tarijs/tsconfig.json +39 -0
- package/packages/tarijs/vitest.config.ts +9 -0
- package/packages/tarijs_types/moon.yml +55 -0
- package/packages/tarijs_types/package.json +27 -0
- package/packages/tarijs_types/src/Amount.ts +113 -0
- package/packages/tarijs_types/src/Arg.ts +3 -0
- package/packages/tarijs_types/src/ComponentAddress.ts +3 -0
- package/packages/tarijs_types/src/ConfidentialClaim.ts +9 -0
- package/packages/tarijs_types/src/ConfidentialOutput.ts +9 -0
- package/packages/tarijs_types/src/ConfidentialOutputStatement.ts +10 -0
- package/packages/tarijs_types/src/ConfidentialStatement.ts +9 -0
- package/packages/tarijs_types/src/ConfidentialWithdrawProof.ts +8 -0
- package/packages/tarijs_types/src/ElgamalVerifiableBalance.ts +4 -0
- package/packages/tarijs_types/src/Epoch.ts +3 -0
- package/packages/tarijs_types/src/FinalizeResult.ts +17 -0
- package/packages/tarijs_types/src/Instruction.ts +29 -0
- package/packages/tarijs_types/src/ResourceAddress.ts +3 -0
- package/packages/tarijs_types/src/SubstateDiff.ts +9 -0
- package/packages/tarijs_types/src/SubstateRequirement.ts +6 -0
- package/packages/tarijs_types/src/TemplateAddress.ts +3 -0
- package/packages/tarijs_types/src/Transaction.ts +16 -0
- package/packages/tarijs_types/src/TransactionId.ts +4 -0
- package/packages/tarijs_types/src/TransactionResult.ts +26 -0
- package/packages/tarijs_types/src/TransactionSignature.ts +4 -0
- package/packages/tarijs_types/src/UnsignedTransaction.ts +15 -0
- package/packages/tarijs_types/src/VersionedSubstateId.ts +6 -0
- package/packages/tarijs_types/src/ViewableBalanceProof.ts +12 -0
- package/packages/tarijs_types/src/Workspace.ts +3 -0
- package/packages/tarijs_types/src/index.ts +25 -0
- package/packages/tarijs_types/tsconfig.json +15 -0
- package/packages/wallet_daemon/moon.yml +55 -0
- package/packages/wallet_daemon/package.json +29 -0
- package/packages/wallet_daemon/src/index.ts +5 -0
- package/packages/wallet_daemon/src/provider.ts +263 -0
- package/packages/wallet_daemon/src/webrtc.ts +229 -0
- package/packages/wallet_daemon/src/webrtc_transport.ts +27 -0
- package/packages/wallet_daemon/tsconfig.json +21 -0
- package/packages/walletconnect/moon.yml +55 -0
- package/packages/walletconnect/package.json +32 -0
- package/packages/walletconnect/src/index.ts +274 -0
- package/packages/walletconnect/tsconfig.json +21 -0
- package/pnpm-workspace.yaml +15 -0
- package/tsconfig.json +45 -0
- package/dist/index.d.ts +0 -14
- package/dist/index.js +0 -13
- package/dist/network.d.ts +0 -8
- package/dist/network.js +0 -9
- package/dist/templates/Account.d.ts +0 -65
- package/dist/templates/Account.js +0 -31
- package/dist/templates/Pool.d.ts +0 -29
- package/dist/templates/Pool.js +0 -20
- package/dist/templates/Tariswap.d.ts +0 -64
- package/dist/templates/Tariswap.js +0 -36
- package/dist/templates/TemplateFactory.d.ts +0 -9
- package/dist/templates/TemplateFactory.js +0 -18
- package/dist/templates/TestFaucet.d.ts +0 -49
- package/dist/templates/TestFaucet.js +0 -31
- package/dist/templates/index.js +0 -5
- package/dist/utils.d.ts +0 -2
- /package/{dist/templates/index.d.ts → packages/tarijs/src/templates/index.ts} +0 -0
|
@@ -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,29 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@tari-project/wallet-daemon-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-permissions": "workspace:^",
|
|
17
|
+
"@tari-project/tari-provider": "workspace:^",
|
|
18
|
+
"@tari-project/wallet_jrpc_client": "catalog:"
|
|
19
|
+
},
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@types/node": "catalog:",
|
|
22
|
+
"typescript": "catalog:"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"/dist"
|
|
26
|
+
],
|
|
27
|
+
"main": "dist/index.js",
|
|
28
|
+
"types": "dist/index.d.ts"
|
|
29
|
+
}
|
|
@@ -0,0 +1,263 @@
|
|
|
1
|
+
import { TariPermissions } from "@tari-project/tari-permissions";
|
|
2
|
+
import { TariConnection } from "./webrtc";
|
|
3
|
+
import { TariProvider } from "@tari-project/tari-provider";
|
|
4
|
+
import {
|
|
5
|
+
SubmitTransactionRequest,
|
|
6
|
+
TransactionResult,
|
|
7
|
+
TransactionStatus,
|
|
8
|
+
SubmitTransactionResponse,
|
|
9
|
+
VaultBalances, TemplateDefinition, Substate,
|
|
10
|
+
ListSubstatesResponse,
|
|
11
|
+
} from "@tari-project/tari-provider";
|
|
12
|
+
import { Account } from "@tari-project/tari-provider";
|
|
13
|
+
import {
|
|
14
|
+
WalletDaemonClient,
|
|
15
|
+
substateIdToString,
|
|
16
|
+
Instruction,
|
|
17
|
+
SubstateType,
|
|
18
|
+
SubstatesListRequest,
|
|
19
|
+
KeyBranch,
|
|
20
|
+
SubstateId,
|
|
21
|
+
} from "@tari-project/wallet_jrpc_client";
|
|
22
|
+
import { WebRtcRpcTransport } from "./webrtc_transport";
|
|
23
|
+
|
|
24
|
+
export const WalletDaemonNotConnected = "WALLET_DAEMON_NOT_CONNECTED";
|
|
25
|
+
export const Unsupported = "UNSUPPORTED";
|
|
26
|
+
|
|
27
|
+
export interface WalletDaemonBaseParameters {
|
|
28
|
+
permissions: TariPermissions,
|
|
29
|
+
optionalPermissions?: TariPermissions,
|
|
30
|
+
onConnection?: () => void
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
export interface WalletDaemonParameters extends WalletDaemonBaseParameters {
|
|
34
|
+
signalingServerUrl?: string,
|
|
35
|
+
webRtcConfig?: RTCConfiguration,
|
|
36
|
+
name?: string,
|
|
37
|
+
};
|
|
38
|
+
|
|
39
|
+
export interface WalletDaemonFetchParameters extends WalletDaemonBaseParameters {
|
|
40
|
+
serverUrl: string,
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export class WalletDaemonTariProvider implements TariProvider {
|
|
44
|
+
public providerName = "WalletDaemon";
|
|
45
|
+
params: WalletDaemonParameters;
|
|
46
|
+
client: WalletDaemonClient;
|
|
47
|
+
|
|
48
|
+
private constructor(params: WalletDaemonParameters, connection: WalletDaemonClient) {
|
|
49
|
+
this.params = params;
|
|
50
|
+
this.client = connection;
|
|
51
|
+
}
|
|
52
|
+
|
|
53
|
+
static async build(params: WalletDaemonParameters): Promise<WalletDaemonTariProvider> {
|
|
54
|
+
const allPermissions = WalletDaemonTariProvider.buildPermissions(params);
|
|
55
|
+
let connection = new TariConnection(params.signalingServerUrl, params.webRtcConfig);
|
|
56
|
+
const client = WalletDaemonClient.new(WebRtcRpcTransport.new(connection));
|
|
57
|
+
await connection.init(allPermissions, (conn) => {
|
|
58
|
+
params.onConnection?.();
|
|
59
|
+
if (conn.token) {
|
|
60
|
+
client.setToken(conn.token);
|
|
61
|
+
}
|
|
62
|
+
});
|
|
63
|
+
return new WalletDaemonTariProvider(params, client);
|
|
64
|
+
}
|
|
65
|
+
|
|
66
|
+
static async buildFetchProvider(params: WalletDaemonFetchParameters) {
|
|
67
|
+
const allPermissions = WalletDaemonTariProvider.buildPermissions(params);
|
|
68
|
+
const client = WalletDaemonClient.usingFetchTransport(params.serverUrl);
|
|
69
|
+
|
|
70
|
+
const plainPermissions = allPermissions.toJSON().flatMap((p) => typeof (p) === "string" ? [p] : []);
|
|
71
|
+
const authResponse = await client.authRequest(plainPermissions);
|
|
72
|
+
await client.authAccept(authResponse, "WalletDaemon");
|
|
73
|
+
|
|
74
|
+
params.onConnection?.();
|
|
75
|
+
return new WalletDaemonTariProvider(params, client);
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
private static buildPermissions(params: WalletDaemonBaseParameters): TariPermissions {
|
|
79
|
+
const allPermissions = new TariPermissions();
|
|
80
|
+
allPermissions.addPermissions(params.permissions);
|
|
81
|
+
if (params.optionalPermissions) {
|
|
82
|
+
allPermissions.addPermissions(params.optionalPermissions);
|
|
83
|
+
}
|
|
84
|
+
return allPermissions;
|
|
85
|
+
}
|
|
86
|
+
|
|
87
|
+
private getWebRtcTransport(): WebRtcRpcTransport | undefined {
|
|
88
|
+
const transport = this.client.getTransport();
|
|
89
|
+
return transport instanceof WebRtcRpcTransport ? transport : undefined;
|
|
90
|
+
}
|
|
91
|
+
|
|
92
|
+
public get token(): string | undefined {
|
|
93
|
+
return this.getWebRtcTransport()?.token();
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
public get tokenUrl(): string | undefined {
|
|
97
|
+
if (!this.token) {
|
|
98
|
+
return undefined;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const name = this.params.name && encodeURIComponent(this.params.name) || "";
|
|
102
|
+
const token = this.token;
|
|
103
|
+
const permissions = JSON.stringify(this.params.permissions);
|
|
104
|
+
const optionalPermissions = JSON.stringify(this.params.optionalPermissions);
|
|
105
|
+
|
|
106
|
+
return `tari://${name}/${token}/${permissions}/${optionalPermissions}`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
public isConnected(): boolean {
|
|
110
|
+
return this.getWebRtcTransport()?.isConnected() || true;
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
public async createFreeTestCoins(): Promise<Account> {
|
|
114
|
+
const res = await this.client.createFreeTestCoins({
|
|
115
|
+
account: { Name: "template_web" },
|
|
116
|
+
amount: 1000000,
|
|
117
|
+
max_fee: null,
|
|
118
|
+
key_id: 0,
|
|
119
|
+
});
|
|
120
|
+
return {
|
|
121
|
+
account_id: res.account.key_index,
|
|
122
|
+
address: (res.account.address as { Component: string }).Component,
|
|
123
|
+
public_key: res.public_key,
|
|
124
|
+
resources: [],
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
public async getAccount(): Promise<Account> {
|
|
129
|
+
const { account, public_key } = await this.client.accountsGetDefault({}) as any;
|
|
130
|
+
const address = typeof account.address === "object" ? account.address.Component : account.address;
|
|
131
|
+
const { balances } = await this.client.accountsGetBalances({
|
|
132
|
+
account: { ComponentAddress: address },
|
|
133
|
+
refresh: false,
|
|
134
|
+
});
|
|
135
|
+
|
|
136
|
+
return {
|
|
137
|
+
account_id: account.key_index,
|
|
138
|
+
address,
|
|
139
|
+
public_key,
|
|
140
|
+
// TODO: should be vaults not resources
|
|
141
|
+
resources: balances.map((b: any) => ({
|
|
142
|
+
type: b.resource_type,
|
|
143
|
+
resource_address: b.resource_address,
|
|
144
|
+
balance: b.balance + b.confidential_balance,
|
|
145
|
+
vault_id: (typeof (b.vault_address) === "object" && "Vault" in b.vault_address) ? b.vault_address.Vault : b.vault_address,
|
|
146
|
+
token_symbol: b.token_symbol,
|
|
147
|
+
})),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
|
|
151
|
+
public async getAccountBalances(componentAddress: string): Promise<unknown> {
|
|
152
|
+
return await this.client.accountsGetBalances({ account: { ComponentAddress: componentAddress }, refresh: true });
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
public async getSubstate(substateId: string): Promise<Substate> {
|
|
156
|
+
// Wallet daemon expects a SubstateId as a string
|
|
157
|
+
const { value, record } = await this.client.substatesGet({ substate_id: substateId as unknown as SubstateId });
|
|
158
|
+
return {
|
|
159
|
+
value,
|
|
160
|
+
address: {
|
|
161
|
+
substate_id: substateIdToString(record.substate_id),
|
|
162
|
+
version: record.version,
|
|
163
|
+
},
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
public async submitTransaction(req: SubmitTransactionRequest): Promise<SubmitTransactionResponse> {
|
|
168
|
+
const params = {
|
|
169
|
+
transaction: {
|
|
170
|
+
V1: {
|
|
171
|
+
network: req.network,
|
|
172
|
+
instructions: req.instructions as Instruction[],
|
|
173
|
+
fee_instructions: req.fee_instructions as Instruction[],
|
|
174
|
+
inputs: req.required_substates.map((s) => ({
|
|
175
|
+
// TODO: Hmm The bindings want a SubstateId object, but the wallet only wants a string. Any is used to skip type checking here
|
|
176
|
+
substate_id: s.substate_id as any,
|
|
177
|
+
version: s.version ?? null,
|
|
178
|
+
})),
|
|
179
|
+
min_epoch: null,
|
|
180
|
+
max_epoch: null,
|
|
181
|
+
is_seal_signer_authorized: req.is_seal_signer_authorized,
|
|
182
|
+
},
|
|
183
|
+
},
|
|
184
|
+
signing_key_index: req.account_id,
|
|
185
|
+
autofill_inputs: [],
|
|
186
|
+
detect_inputs: true,
|
|
187
|
+
proof_ids: [],
|
|
188
|
+
detect_inputs_use_unversioned: req.detect_inputs_use_unversioned,
|
|
189
|
+
};
|
|
190
|
+
|
|
191
|
+
const res = await this.client.submitTransaction(params);
|
|
192
|
+
return { transaction_id: res.transaction_id };
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
public async getTransactionResult(transactionId: string): Promise<TransactionResult> {
|
|
196
|
+
const res = await this.client.getTransactionResult({ transaction_id: transactionId });
|
|
197
|
+
|
|
198
|
+
return {
|
|
199
|
+
transaction_id: transactionId,
|
|
200
|
+
status: convertStringToTransactionStatus(res.status),
|
|
201
|
+
result: res.result,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
public async getPublicKey(branch: string, index: number): Promise<string> {
|
|
206
|
+
const res = await this.client.createKey({ branch: branch as KeyBranch, specific_index: index });
|
|
207
|
+
return res.public_key;
|
|
208
|
+
}
|
|
209
|
+
|
|
210
|
+
public async getTemplateDefinition(template_address: string): Promise<TemplateDefinition> {
|
|
211
|
+
let resp = await this.client.templatesGet({ template_address });
|
|
212
|
+
return resp.template_definition as TemplateDefinition;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
public async getConfidentialVaultBalances(viewKeyId: number, vaultId: string, min: number | null = null, max: number | null = null): Promise<VaultBalances> {
|
|
216
|
+
const res = await this.client.viewVaultBalance({
|
|
217
|
+
view_key_id: viewKeyId,
|
|
218
|
+
vault_id: vaultId,
|
|
219
|
+
minimum_expected_value: min,
|
|
220
|
+
maximum_expected_value: max,
|
|
221
|
+
});
|
|
222
|
+
return { balances: res.balances as unknown as Map<string, number | null> };
|
|
223
|
+
}
|
|
224
|
+
|
|
225
|
+
public async listSubstates(filter_by_template: string | null, filter_by_type: SubstateType | null, limit: number | null, offset: number | null): Promise<ListSubstatesResponse> {
|
|
226
|
+
const resp = await this.client.substatesList({
|
|
227
|
+
filter_by_template,
|
|
228
|
+
filter_by_type,
|
|
229
|
+
limit,
|
|
230
|
+
offset,
|
|
231
|
+
} as SubstatesListRequest);
|
|
232
|
+
|
|
233
|
+
const substates = resp.substates.map((s) => ({
|
|
234
|
+
substate_id: typeof s.substate_id === "string" ? s.substate_id : substateIdToString(s.substate_id),
|
|
235
|
+
module_name: s.module_name,
|
|
236
|
+
version: s.version,
|
|
237
|
+
template_address: s.template_address,
|
|
238
|
+
}));
|
|
239
|
+
|
|
240
|
+
return { substates };
|
|
241
|
+
}
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
function convertStringToTransactionStatus(status: string): TransactionStatus {
|
|
245
|
+
switch (status) {
|
|
246
|
+
case "New":
|
|
247
|
+
return TransactionStatus.New;
|
|
248
|
+
case "DryRun":
|
|
249
|
+
return TransactionStatus.DryRun;
|
|
250
|
+
case "Pending":
|
|
251
|
+
return TransactionStatus.Pending;
|
|
252
|
+
case "Accepted":
|
|
253
|
+
return TransactionStatus.Accepted;
|
|
254
|
+
case "Rejected":
|
|
255
|
+
return TransactionStatus.Rejected;
|
|
256
|
+
case "InvalidTransaction":
|
|
257
|
+
return TransactionStatus.InvalidTransaction;
|
|
258
|
+
case "OnlyFeeAccepted":
|
|
259
|
+
return TransactionStatus.OnlyFeeAccepted;
|
|
260
|
+
default:
|
|
261
|
+
throw new Error(`Unknown status: ${status}`);
|
|
262
|
+
}
|
|
263
|
+
}
|
|
@@ -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)"
|