@dfns/lib-hedera 0.7.12

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 (3) hide show
  1. package/index.d.ts +33 -0
  2. package/index.js +163 -0
  3. package/package.json +9 -0
package/index.d.ts ADDED
@@ -0,0 +1,33 @@
1
+ import { DfnsApiClient } from '@dfns/sdk';
2
+ import { AccountId, PublicKey, Transaction, Signer, Provider, LedgerId, Executable, SignerSignature, AccountBalance, AccountInfo, TransactionRecord } from '@hashgraph/sdk';
3
+ export declare const hexToBuffer: (hex: string) => Buffer;
4
+ export type DfnsWalletOptions = {
5
+ walletId: string;
6
+ dfnsClient: DfnsApiClient;
7
+ };
8
+ export declare class DfnsWallet implements Signer {
9
+ private readonly provider;
10
+ private readonly publicKey;
11
+ private readonly accountId;
12
+ private readonly dfnsClient;
13
+ private readonly walletId;
14
+ private constructor();
15
+ static init(options: DfnsWalletOptions): Promise<DfnsWallet>;
16
+ signTransaction<T extends Transaction>(transaction: T): Promise<T>;
17
+ getProvider(): Provider;
18
+ getLedgerId(): LedgerId | null;
19
+ getAccountId(): AccountId;
20
+ getNetwork(): {
21
+ [key: string]: string | AccountId;
22
+ };
23
+ getMirrorNetwork(): string[];
24
+ getAccountKey(): PublicKey;
25
+ getAccountBalance(): Promise<AccountBalance>;
26
+ getAccountInfo(): Promise<AccountInfo>;
27
+ getAccountRecords(): Promise<TransactionRecord[]>;
28
+ sign(_messages: Uint8Array[]): Promise<SignerSignature[]>;
29
+ checkTransaction<T extends Transaction>(transaction: T): Promise<T>;
30
+ populateTransaction<T extends Transaction>(transaction: T): Promise<T>;
31
+ call<RequestT, ResponseT, OutputT>(request: Executable<RequestT, ResponseT, OutputT>): Promise<OutputT>;
32
+ close(): void;
33
+ }
package/index.js ADDED
@@ -0,0 +1,163 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DfnsWallet = exports.hexToBuffer = void 0;
4
+ const sdk_1 = require("@dfns/sdk");
5
+ const sdk_2 = require("@hashgraph/sdk");
6
+ const hexToBuffer = (hex) => {
7
+ return Buffer.from(stripHexPrefix(hex), 'hex');
8
+ };
9
+ exports.hexToBuffer = hexToBuffer;
10
+ const stripHexPrefix = (hex) => {
11
+ return hex.replace(/^0x/, '');
12
+ };
13
+ const assertSignResponseSuccessful = (response) => {
14
+ if (response.status === 'Failed') {
15
+ throw new sdk_1.DfnsError(-1, 'signing failed', response);
16
+ }
17
+ else if (response.status !== 'Signed') {
18
+ throw new sdk_1.DfnsError(-1, 'cannot complete signing synchronously because this wallet action requires policy approval', response);
19
+ }
20
+ else if (!response.signature || !response.signature.encoded) {
21
+ throw new sdk_1.DfnsError(-1, 'signature missing', response);
22
+ }
23
+ };
24
+ class DfnsWallet {
25
+ constructor(dfnsOptions, provider, publicKey, accountId) {
26
+ this.provider = provider;
27
+ this.publicKey = publicKey;
28
+ this.accountId = accountId;
29
+ this.dfnsClient = dfnsOptions.dfnsClient;
30
+ this.walletId = dfnsOptions.walletId;
31
+ }
32
+ static async init(options) {
33
+ const { walletId, dfnsClient } = options;
34
+ const res = await dfnsClient.wallets.getWallet({ walletId });
35
+ if (res.status !== 'Active') {
36
+ throw new sdk_1.DfnsError(-1, 'wallet not active', { walletId, status: res.status });
37
+ }
38
+ if (res.network !== 'Hedera' && res.network !== 'HederaTestnet') {
39
+ throw new sdk_1.DfnsError(-1, 'wallet is not bound to a Hedera network', {
40
+ walletId,
41
+ network: res.network,
42
+ });
43
+ }
44
+ const nativeAddressRegex = /^0\.0\.\d+$/;
45
+ if (!nativeAddressRegex.test(res.address)) {
46
+ throw new sdk_1.DfnsError(-1, 'account must be created. Address is not in native Hedera format (0.0.x)', {
47
+ walletId,
48
+ address: res.address
49
+ });
50
+ }
51
+ const accountId = sdk_2.AccountId.fromString(res.address);
52
+ if (!res.signingKey?.publicKey) {
53
+ throw new sdk_1.DfnsError(-1, 'wallet public key not found', { walletId });
54
+ }
55
+ const publicKey = sdk_2.PublicKey.fromString(res.signingKey.publicKey);
56
+ const client = res.network === 'HederaTestnet'
57
+ ? sdk_2.Client.forTestnet()
58
+ : sdk_2.Client.forMainnet();
59
+ return new DfnsWallet(options, new sdk_2.LocalProvider({ client }), publicKey, accountId);
60
+ }
61
+ async signTransaction(transaction) {
62
+ if (!transaction.isFrozen()) {
63
+ transaction.freeze();
64
+ }
65
+ const transactionBytes = transaction.toBytes();
66
+ const messageHex = '0x' + Buffer.from(transactionBytes).toString('hex');
67
+ const response = await this.dfnsClient.wallets.generateSignature({
68
+ walletId: this.walletId,
69
+ body: {
70
+ kind: 'Transaction',
71
+ transaction: messageHex,
72
+ },
73
+ });
74
+ assertSignResponseSuccessful(response);
75
+ const signature = response.signature;
76
+ if (!signature?.encoded) {
77
+ throw new sdk_1.DfnsError(-1, 'signature encoded value missing', response);
78
+ }
79
+ if (!response.signedData) {
80
+ throw new sdk_1.DfnsError(-1, 'signed data missing', response);
81
+ }
82
+ const signedTx = sdk_2.Transaction.fromBytes(new Uint8Array((0, exports.hexToBuffer)(response.signedData)));
83
+ transaction.addSignature(this.getAccountKey(), signedTx.getSignatures());
84
+ return transaction;
85
+ }
86
+ getProvider() {
87
+ return this.provider;
88
+ }
89
+ getLedgerId() {
90
+ return this.provider.getLedgerId();
91
+ }
92
+ getAccountId() {
93
+ return this.accountId;
94
+ }
95
+ getNetwork() {
96
+ return this.provider.getNetwork();
97
+ }
98
+ getMirrorNetwork() {
99
+ return this.provider.getMirrorNetwork();
100
+ }
101
+ getAccountKey() {
102
+ return this.publicKey;
103
+ }
104
+ getAccountBalance() {
105
+ return this.call(new sdk_2.AccountBalanceQuery().setAccountId(this.accountId));
106
+ }
107
+ getAccountInfo() {
108
+ return this.call(new sdk_2.AccountInfoQuery().setAccountId(this.accountId));
109
+ }
110
+ getAccountRecords() {
111
+ return this.call(new sdk_2.AccountRecordsQuery().setAccountId(this.accountId));
112
+ }
113
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
114
+ sign(_messages) {
115
+ throw new sdk_1.DfnsError(-1, 'sign method not implemented', {});
116
+ }
117
+ async checkTransaction(transaction) {
118
+ const transactionId = transaction.transactionId;
119
+ if (transactionId?.accountId && transactionId.accountId.compare(this.accountId) !== 0) {
120
+ throw new sdk_1.DfnsError(-1, "transaction's ID constructed with a different account ID", {
121
+ transactionAccountId: transactionId.accountId.toString(),
122
+ walletAccountId: this.accountId.toString(),
123
+ });
124
+ }
125
+ if (!this.provider) {
126
+ return transaction;
127
+ }
128
+ const nodeAccountIds = (transaction.nodeAccountIds ?? []).map((nodeAccountId) => nodeAccountId.toString());
129
+ const network = Object.values(this.provider.getNetwork()).map((nodeAccountId) => nodeAccountId.toString());
130
+ const allNodeIdsInNetwork = nodeAccountIds.every((nodeId) => network.includes(nodeId));
131
+ if (!allNodeIdsInNetwork) {
132
+ throw new sdk_1.DfnsError(-1, 'Transaction already set node account IDs to values not within the current network', {
133
+ transactionNodeIds: nodeAccountIds,
134
+ networkNodeIds: network,
135
+ });
136
+ }
137
+ return transaction;
138
+ }
139
+ async populateTransaction(transaction) {
140
+ const accountId = this.getAccountId();
141
+ transaction._freezeWithAccountId(accountId);
142
+ if (transaction.transactionId == null) {
143
+ transaction.setTransactionId(sdk_2.TransactionId.generate(accountId));
144
+ }
145
+ if (transaction.nodeAccountIds != null &&
146
+ transaction.nodeAccountIds.length != 0) {
147
+ return Promise.resolve(transaction.freeze());
148
+ }
149
+ if (this.provider == null) {
150
+ return Promise.resolve(transaction);
151
+ }
152
+ const nodeAccountIds = Object.values(this.provider.getNetwork()).map((id) => (typeof id === "string" ? sdk_2.AccountId.fromString(id) : id));
153
+ transaction.setNodeAccountIds([nodeAccountIds[0]]);
154
+ return Promise.resolve(transaction.freeze());
155
+ }
156
+ call(request) {
157
+ return this.provider.call(request);
158
+ }
159
+ close() {
160
+ this.provider.close();
161
+ }
162
+ }
163
+ exports.DfnsWallet = DfnsWallet;
package/package.json ADDED
@@ -0,0 +1,9 @@
1
+ {
2
+ "name": "@dfns/lib-hedera",
3
+ "version": "0.7.12",
4
+ "peerDependencies": {
5
+ "@hashgraph/sdk": "^2.70.0"
6
+ },
7
+ "main": "./index.js",
8
+ "type": "commonjs"
9
+ }