Closed YakovL closed 1 year ago
You can use sign
in ripple-keypairs
with a private key if you encode the transaction using encodeForSigning
in ripple-binary-codec
.
Thanks! Can I somehow use the result with client.submitAndWait
?
Here's what I'm trying to do:
import { sign } from "ripple-keypairs";
import { encodeForSigning } from "ripple-binary-codec";
...
await client.connect();
const transaction: Transaction = {
TransactionType: "Payment",
Account: address,
Amount: amount,
Destination: recipientAddress,
};
const preparedTransaction = await client.autofill(transaction);
const preparedTransactionHex = encodeForSigning(preparedTransaction);
const signedTransaction = sign(preparedTransactionHex, privateKey);
const tentativeResultTx = await client.submitAndWait(signedTransaction); // this is ripple.ts:204:52
but for the last line I'm getting
TypeError: Cannot read properties of undefined (reading 'name')
at Function.STObject.fromParser (<project folder>\node_modules\ripple-binary-codec\src\types\st-object.ts:66:17)
at BinaryParser.readType (<project folder>\node_modules\ripple-binary-codec\src\serdes\binary-parser.ts:159:17)
at readJSON (<project folder>\node_modules\ripple-binary-codec\src\binary.ts:30:11)
at binaryToJSON (<project folder>\node_modules\ripple-binary-codec\src\binary.ts:38:53)
at decode (<project folder>\node_modules\ripple-binary-codec\src\index.ts:24:10)
at isSigned (<project folder>\node_modules\xrpl\src\sugar\submit.ts:164:54)
at <project folder>\node_modules\xrpl\src\sugar\submit.ts:187:7
at Generator.next (<anonymous>)
at <project folder>\node_modules\xrpl\dist\npm\sugar\submit.js:8:71
at new Promise (<anonymous>)
at __awaiter (<project folder>\node_modules\xrpl\dist\npm\sugar\submit.js:4:12)
at getSignedTx (<project folder>\node_modules\xrpl\dist\npm\sugar\submit.js:94:12)
at Client.<anonymous> (<project folder>\node_modules\xrpl\src\sugar\submit.ts:75:26)
at Generator.next (<anonymous>)
at <project folder>\node_modules\xrpl\dist\npm\sugar\submit.js:8:71
at new Promise (<anonymous>)
at __awaiter (<project folder>\node_modules\xrpl\dist\npm\sugar\submit.js:4:12)
at Client.submitAndWait (<project folder>\node_modules\xrpl\dist\npm\sugar\submit.js:32:12)
at Ripple.sendNativeToken (<project folder>\src\implementations\ripple.ts:204:52)
at processTicksAndRejections (node:internal/process/task_queues:96:5)
at Context.<anonymous> (<project folder>\test\ripple.test.ts:555:24)
Any ideas what can be wrong?
console.log(signedTransaction)
gives 304402202124E9F4F2B5A30904E1C10863BB2E55D78A7E4422931F952F3A5D177C3819F002202C4F3CA62FD5B276BFDF378907BB5D029CAD0822315EDDBD3E5816684BDFD140
. Not sure why the reading 'name'
error, submitAndWait
allows string
argument; presumably this is something internal.
sign
just generates the signature. You need to submit the whole transaction blob, because otherwise rippled doesn't know what the transaction is (you can't really get the transaction details from the signature).
What you want is something like this:
const preparedTransaction = await client.autofill(transaction);
const preparedTransactionHex = encodeForSigning(preparedTransaction);
const signature = sign(preparedTransactionHex, privateKey);
preparedTransaction["TxnSignature"] = signature
preparedTransaction["SigningPublicKey"] = publicKey;
const tentativeResultTx = await client.submitAndWait(preparedTransaction)
Thanks! This gives an idea of what this can look like; however, the signature doesn't seem to be correct. When I try
await client.connect();
const transaction: Transaction = {
TransactionType: "Payment",
Account: address,
Amount: amount, // ~integer in "drops" of XRP, where 1,000,000 drops equals 1 XRP
Destination: to,
};
const preparedTransaction = await client.autofill(transaction);
const preparedTransactionHex = encodeForSigning(preparedTransaction);
const signature = sign(preparedTransactionHex, privateKey);
preparedTransaction.TxnSignature = signature;
preparedTransaction.SigningPubKey = publicKey;
const tentativeResultTx = await client.submitAndWait(preparedTransaction);
I'm getting RippledError: invalidTransaction
with error_exception: 'fails local checks: Invalid signature.'
Since there's no detail, I'm not really sure what's the source of the problem/how to debug.
Because I'm trying this in testnet with a test account, I can share the credentials to repduce this:
address: rDKTggHSR3ovNNYMk1bxCR5Z7hE9Szmos6 publicKey: 036F9888A9C4E30AD59053D6640BCA5FF54809B146E19BA272EEC06D6913406053 privateKey: 00D8DC02C0E95CD83E720180EEAFA2A3FD580A762C17010525CC3650008A4AB000
Any ideas what could have gone wrong?
You need to include the SigningPubKey
in the signature when signing.
await client.connect();
const transaction: Transaction = {
TransactionType: "Payment",
Account: address,
Amount: amount, // ~integer in "drops" of XRP, where 1,000,000 drops equals 1 XRP
Destination: to,
};
const preparedTransaction = await client.autofill(transaction);
preparedTransaction.SigningPubKey = publicKey; // HERE: move this up above the encoding
const preparedTransactionHex = encodeForSigning(preparedTransaction);
const signature = sign(preparedTransactionHex, privateKey);
preparedTransaction.TxnSignature = signature;
const tentativeResultTx = await client.submitAndWait(preparedTransaction);
As far as I understand, this should be possible. On the other hand, basic example provided by docs uses
Wallet
which can't be created from private key (as far as I understand; at least it only has methodsfromSeed
,fromSecret
,fromMnemonic
andfromEntropy
).I've found the
sign
method in another library,ripple-keypairs
(searching by "sign" in this repo), butawait client.autofill(transaction)
returnsxrpl.Payment
andsign
expects hex as the first argument.Can anyone help with getting a signed tx via either
ripple-keypairs
'ssign
(how toxrpl.Payment
to hex?) or viaxrpl
itself?