@hashgraph/hedera-wallet-connect 2.0.5-canary.7b24ac9.0 → 2.0.5-canary.86bf72d.0
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/README.md +0 -135
- package/dist/lib/shared/utils.js +1 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -211,141 +211,6 @@ createAppKit({
|
|
|
211
211
|
- [Hedera Wallet Example by Hgraph](https://github.com/hgraph-io/hedera-wallet)
|
|
212
212
|
- <em>[Add an example, demo, or tool here](https://github.com/hashgraph/hedera-wallet-connect/pulls)</em>
|
|
213
213
|
|
|
214
|
-
# Multi-Signature Transactions
|
|
215
|
-
|
|
216
|
-
Multi-signature (multi-sig) workflows allow multiple parties to sign a single transaction before it's executed on the Hedera network. This is commonly used for:
|
|
217
|
-
|
|
218
|
-
- Treasury operations requiring approval from multiple parties
|
|
219
|
-
- Escrow services
|
|
220
|
-
- Joint accounts
|
|
221
|
-
- Backend co-signing for additional security
|
|
222
|
-
|
|
223
|
-
## Using `hedera_signTransaction` for Multi-Sig Workflows
|
|
224
|
-
|
|
225
|
-
The `hedera_signTransaction` method allows you to collect a signature from a wallet without immediately executing the transaction. This signature can then be combined with additional signatures (such as from a backend service) before final execution.
|
|
226
|
-
|
|
227
|
-
### Example: Frontend Wallet Signature + Backend Co-Signature
|
|
228
|
-
|
|
229
|
-
This example demonstrates a common pattern where a user signs a transaction in their wallet, and then a backend service adds its signature before executing the transaction.
|
|
230
|
-
|
|
231
|
-
#### Step 1: Create and Sign Transaction on Frontend
|
|
232
|
-
|
|
233
|
-
```typescript
|
|
234
|
-
import { DAppConnector, HederaJsonRpcMethod } from '@hashgraph/hedera-wallet-connect'
|
|
235
|
-
import { TransferTransaction, Hbar, AccountId } from '@hashgraph/sdk'
|
|
236
|
-
|
|
237
|
-
// Initialize your DAppConnector (see Getting Started section)
|
|
238
|
-
const dAppConnector = new DAppConnector(/* ... */)
|
|
239
|
-
|
|
240
|
-
// Create a transaction
|
|
241
|
-
const transaction = new TransferTransaction()
|
|
242
|
-
.addHbarTransfer(userAccountId, new Hbar(-10))
|
|
243
|
-
.addHbarTransfer(recipientAccountId, new Hbar(10))
|
|
244
|
-
.setTransactionMemo('Multi-sig transfer')
|
|
245
|
-
|
|
246
|
-
// Request signature from wallet (does NOT execute)
|
|
247
|
-
const signer = dAppConnector.getSigner(userAccountId)
|
|
248
|
-
const signedTransaction = await signer.signTransaction(transaction)
|
|
249
|
-
|
|
250
|
-
// Convert signed transaction to bytes for transmission to backend
|
|
251
|
-
const signedTransactionBytes = signedTransaction.toBytes()
|
|
252
|
-
|
|
253
|
-
// Send to backend
|
|
254
|
-
const response = await fetch('/api/execute-transaction', {
|
|
255
|
-
method: 'POST',
|
|
256
|
-
headers: { 'Content-Type': 'application/json' },
|
|
257
|
-
body: JSON.stringify({
|
|
258
|
-
signedTransaction: Buffer.from(signedTransactionBytes).toString('base64'),
|
|
259
|
-
}),
|
|
260
|
-
})
|
|
261
|
-
|
|
262
|
-
const result = await response.json()
|
|
263
|
-
console.log('Transaction executed:', result.transactionId)
|
|
264
|
-
```
|
|
265
|
-
|
|
266
|
-
#### Step 2: Add Backend Signature and Execute
|
|
267
|
-
|
|
268
|
-
On your backend, use the `addSignatureToTransaction` utility to add your server's signature:
|
|
269
|
-
|
|
270
|
-
```typescript
|
|
271
|
-
import { Transaction, PrivateKey, Client } from '@hashgraph/sdk'
|
|
272
|
-
import { addSignatureToTransaction } from '@hashgraph/hedera-wallet-connect'
|
|
273
|
-
|
|
274
|
-
// Backend API endpoint
|
|
275
|
-
app.post('/api/execute-transaction', async (req, res) => {
|
|
276
|
-
try {
|
|
277
|
-
// Reconstruct transaction from bytes
|
|
278
|
-
const signedTransactionBytes = Buffer.from(req.body.signedTransaction, 'base64')
|
|
279
|
-
const signedTransaction = Transaction.fromBytes(signedTransactionBytes)
|
|
280
|
-
|
|
281
|
-
// Load your backend private key (store securely!)
|
|
282
|
-
const backendPrivateKey = PrivateKey.fromStringED25519(process.env.BACKEND_PRIVATE_KEY)
|
|
283
|
-
|
|
284
|
-
// Add backend signature to the transaction
|
|
285
|
-
const fullySignedTransaction = await addSignatureToTransaction(
|
|
286
|
-
signedTransaction,
|
|
287
|
-
backendPrivateKey,
|
|
288
|
-
)
|
|
289
|
-
|
|
290
|
-
// Execute the fully signed transaction
|
|
291
|
-
const client = Client.forTestnet() // or Client.forMainnet()
|
|
292
|
-
client.setOperator(backendAccountId, backendPrivateKey)
|
|
293
|
-
|
|
294
|
-
const txResponse = await fullySignedTransaction.execute(client)
|
|
295
|
-
const receipt = await txResponse.getReceipt(client)
|
|
296
|
-
|
|
297
|
-
res.json({
|
|
298
|
-
success: true,
|
|
299
|
-
transactionId: txResponse.transactionId.toString(),
|
|
300
|
-
status: receipt.status.toString(),
|
|
301
|
-
})
|
|
302
|
-
} catch (error) {
|
|
303
|
-
console.error('Error executing transaction:', error)
|
|
304
|
-
res.status(500).json({ error: error.message })
|
|
305
|
-
}
|
|
306
|
-
})
|
|
307
|
-
```
|
|
308
|
-
|
|
309
|
-
### Important Notes
|
|
310
|
-
|
|
311
|
-
1. **Transaction Must Be Frozen**: Before signing, ensure your transaction is frozen.
|
|
312
|
-
|
|
313
|
-
2. **Signature Order**: Signatures can be added in any order. Hedera validates that all required signatures are present when the transaction is executed.
|
|
314
|
-
|
|
315
|
-
3. **Security Considerations**:
|
|
316
|
-
- Never expose backend private keys to the frontend
|
|
317
|
-
- Validate transaction contents on the backend before adding your signature
|
|
318
|
-
- Implement proper authentication and authorization
|
|
319
|
-
- Consider implementing transaction limits and approval workflows
|
|
320
|
-
|
|
321
|
-
4. **Multiple Signatures**: You can add more than two signatures using the same pattern:
|
|
322
|
-
|
|
323
|
-
```typescript
|
|
324
|
-
// Add multiple signatures sequentially
|
|
325
|
-
let signedTx = await addSignatureToTransaction(transaction, privateKey1)
|
|
326
|
-
signedTx = await addSignatureToTransaction(signedTx, privateKey2)
|
|
327
|
-
signedTx = await addSignatureToTransaction(signedTx, privateKey3)
|
|
328
|
-
|
|
329
|
-
// Execute with all signatures
|
|
330
|
-
await signedTx.execute(client)
|
|
331
|
-
```
|
|
332
|
-
|
|
333
|
-
5. **Threshold Keys**: For accounts with threshold key structures, ensure you collect enough signatures to meet the threshold requirement before execution.
|
|
334
|
-
|
|
335
|
-
### Alternative: Using `hedera_signAndExecuteTransaction`
|
|
336
|
-
|
|
337
|
-
If you don't need backend co-signing and want the wallet to execute the transaction immediately:
|
|
338
|
-
|
|
339
|
-
```typescript
|
|
340
|
-
// This signs AND executes in one call
|
|
341
|
-
const result = await dAppConnector.signAndExecuteTransaction({
|
|
342
|
-
signerAccountId: `hedera:testnet:${userAccountId}`,
|
|
343
|
-
transactionList: transactionToBase64String(transaction),
|
|
344
|
-
})
|
|
345
|
-
```
|
|
346
|
-
|
|
347
|
-
Use `hedera_signTransaction` when you need to collect multiple signatures. Use `hedera_signAndExecuteTransaction` when the wallet's signature alone is sufficient to execute the transaction.
|
|
348
|
-
|
|
349
214
|
# Hedera Wallets
|
|
350
215
|
|
|
351
216
|
- [Hashpack](https://hashpack.app/)
|
package/dist/lib/shared/utils.js
CHANGED
|
@@ -454,8 +454,6 @@ export async function addSignatureToTransaction(transaction, privateKey) {
|
|
|
454
454
|
return Object.assign(Object.assign({}, tx), { sigMap: Object.assign(Object.assign({}, existingSigMap), { sigPair: mergedSigPairs }) });
|
|
455
455
|
}
|
|
456
456
|
});
|
|
457
|
-
const signedBytes = proto.TransactionList.encode({
|
|
458
|
-
transactionList: signedTransactionList,
|
|
459
|
-
}).finish();
|
|
457
|
+
const signedBytes = proto.TransactionList.encode({ transactionList: signedTransactionList }).finish();
|
|
460
458
|
return Transaction.fromBytes(signedBytes);
|
|
461
459
|
}
|
package/package.json
CHANGED