Skip to content

Commit

Permalink
fix: sign input
Browse files Browse the repository at this point in the history
  • Loading branch information
witter-deland committed Dec 8, 2024
1 parent 7cc8247 commit 67bb0c3
Show file tree
Hide file tree
Showing 8 changed files with 265 additions and 108 deletions.
1 change: 1 addition & 0 deletions packages/coin-kaspa-rpc/src/lib/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@ export * from './consensus';
export { Keypair } from './keypair';
export { kaspaToSompi, addressFromScriptPublicKey } from './utils';
export { Resolver } from './resolver';
export { SendKasPramas, SendKrc20Pramas } from './send-param';
149 changes: 149 additions & 0 deletions packages/coin-kaspa-rpc/src/lib/send-param.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,149 @@
import { Address } from './address';
import { Fees, GeneratorSettings, PaymentOutput, TransactionId, TransactionOutpoint, UtxoEntryReference } from './tx';
import { addressFromScriptPublicKey, kaspaToSompi } from './utils';
import { OpCodes, ScriptBuilder } from './tx-script';
import { NetworkId } from './consensus';

/**
* Class representing parameters for sending Kaspa.
*/
class SendKasPramas {
sender: Address;
amount: bigint;
receiver: Address;
networkId: NetworkId;
priorityFee?: Fees;

/**
* Creates an instance of SendKasPramas.
* @param sender - The sender's address.
* @param amount - The amount to send.
* @param receiver - The receiver's address.
* @param networkId - The network ID.
* @param priorityFee - The optional priority fee.
*/
constructor(
sender: Address | string,
amount: bigint,
receiver: Address | string,
networkId: NetworkId,
priorityFee?: Fees
) {
this.sender = sender instanceof Address ? sender : Address.fromString(sender);
this.amount = amount;
this.receiver = receiver instanceof Address ? receiver : Address.fromString(receiver);
this.networkId = networkId;
this.priorityFee = priorityFee;
}

/**
* Converts the parameters to generator settings.
* @param uxtos - The UTXO entries.
* @returns The generator settings.
*/
toGeneratorSettings(uxtos: UtxoEntryReference[] = []): GeneratorSettings {
const output = new PaymentOutput(this.receiver, this.amount);
return new GeneratorSettings(output, this.sender, uxtos, this.networkId, this.priorityFee);
}
}

/**
* Class representing parameters for sending KRC-20 tokens.
*/
class SendKrc20Pramas {
sender: Address;
amount: bigint;
receiver: Address;
tick: string;
networkId: NetworkId;
priorityFee?: Fees;

/**
* Creates an instance of SendKrc20Pramas.
* @param sender - The sender's address.
* @param amount - The amount to send.
* @param receiver - The receiver's address.
* @param tick - The token ticker.
* @param networkId - The network ID.
* @param priorityFee - The optional priority fee.
*/
constructor(
sender: Address | string,
amount: bigint,
receiver: Address | string,
tick: string,
networkId: NetworkId,
priorityFee?: Fees
) {
this.sender = sender instanceof Address ? sender : Address.fromString(sender);
this.amount = amount;
this.receiver = receiver instanceof Address ? receiver : Address.fromString(receiver);
this.tick = tick.toUpperCase();
this.networkId = networkId;
this.priorityFee = priorityFee;
}

/**
* Converts the parameters to commit transaction generator settings.
* @param uxtos - The UTXO entries.
* @returns The generator settings.
*/
toCommitTxGeneratorSettings(uxtos: UtxoEntryReference[] = []): GeneratorSettings {
const P2SHAddress = addressFromScriptPublicKey(
this.script.createPayToScriptHashScript(),
this.networkId.networkType
)!;

const output = new PaymentOutput(P2SHAddress, kaspaToSompi(0.3));
return new GeneratorSettings(output, this.sender, uxtos, this.networkId, this.priorityFee);
}

/**
* Converts the parameters to reveal transaction generator settings.
* @param uxtos - The UTXO entries.
* @param commitTxId - The commit transaction ID.
* @returns The generator settings.
*/
toRevealTxGeneratorSettings(uxtos: UtxoEntryReference[] = [], commitTxId: TransactionId): GeneratorSettings {
const P2SHAddress = addressFromScriptPublicKey(
this.script.createPayToScriptHashScript(),
this.networkId.networkType
)!;
const priorityEntries = [
new UtxoEntryReference(
P2SHAddress,
new TransactionOutpoint(commitTxId, 0),
kaspaToSompi(0.3),
this.script.createPayToScriptHashScript(),
0n,
false
)
];
return new GeneratorSettings([], this.sender, uxtos, this.networkId, this.priorityFee, priorityEntries);
}

/**
* Gets the script builder for the transaction.
* @returns The script builder.
*/
get script(): ScriptBuilder {
const data = {
p: 'krc-20',
op: 'transfer',
tick: this.tick,
amt: this.amount.toString(),
to: this.receiver.toString()
};
return new ScriptBuilder()
.addData(this.sender.payload)
.addOp(OpCodes.OpCheckSig)
.addOp(OpCodes.OpFalse)
.addOp(OpCodes.OpIf)
.addData(Buffer.from('kasplex'))
.addI64(0n)
.addData(Buffer.from(JSON.stringify(data, null, 0)))
.addOp(OpCodes.OpEndIf);
}
}

export { SendKasPramas, SendKrc20Pramas };
5 changes: 2 additions & 3 deletions packages/coin-kaspa-rpc/src/lib/tx-script/script-builder.ts
Original file line number Diff line number Diff line change
Expand Up @@ -202,10 +202,9 @@ class ScriptBuilder {
* @param {Uint8Array} signature - The signature.
* @returns {string} The hex string representation of the generated script.
*/
encodePayToScriptHashSignatureScript(signature: Uint8Array): string {
encodePayToScriptHashSignatureScript(signature: Uint8Array): Uint8Array {
const script = this.script;
const generatedScript = payToScriptHashSignatureScript(script, signature);
return base.toHex(generatedScript);
return payToScriptHashSignatureScript(script, signature);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion packages/coin-kaspa-rpc/src/lib/tx/hashing/sign.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ function signInput(
const sig = schnorrKey.sign(msg);

// This represents OP_DATA_65 <SIGNATURE+SIGHASH_TYPE> (since signature length is 64 bytes and SIGHASH_TYPE is one byte)
return new Uint8Array([64, ...sig, hashType.value]);
return new Uint8Array([65, ...sig, hashType.value]);
}

/**
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
[
{
"id": "b79c20749967fab0138cb5224281d7e5d7b2123b02f1004bac705c0da4c8f6ca",
"paymentAmount": "0n",
"changeAmount": "27997619n",
"feeAmount": "2002381n",
"mass": "2384n",
"minimumSignatures": 1,
"aggregateInputAmount": "30000000n",
"aggregateOutputAmount": "27997619n",
"type": "final",
"transaction": {
"id": "b79c20749967fab0138cb5224281d7e5d7b2123b02f1004bac705c0da4c8f6ca",
"inputs": [
{
"previousOutpoint": {
"transactionId": "5c1ddb4494ac8eb6488808c8be89f91e76402da497182a271eaec9227a10a1ea",
"index": 0
},
"signatureScript": "4141329a9ea0105f92c64fe777fa065dc4a2ee3f3a111f0def4fefcefa53e5e7e797363bee641f3ac752d4d7ddfd4972ff73df52b7b8054db5cc14c0f8f85d178e014cbf208426329e968fbc322383543cc2f75b2a3c3aa6c1e13be66155aaee57f17c9323ac0063076b6173706c6578004c8f7b2270223a226b72632d3230222c226f70223a227472616e73666572222c227469636b223a224b415354222c22616d74223a223130313030303030303030222c22746f223a226b61737061746573743a71726a6367376873676a6170756d706e386567797536353434717a647173326c73736173346e667765776c35356c6e656e723570797a6437636d797836227d68",
"sequence": "0n",
"sigOpCount": 1,
"utxo": {
"entry": {
"address": {
"version": "ScriptHash",
"prefix": "kaspatest",
"payload": "pz6gd03xxw0hy6aj4mrnqq8pcrwgxafc986fh2ky030csevvvaeeuysw0srlr"
},
"outpoint": {
"transactionId": "5c1ddb4494ac8eb6488808c8be89f91e76402da497182a271eaec9227a10a1ea",
"index": 0
},
"amount": "30000000n",
"scriptPublicKey": {
"version": 0,
"script": "aa20b486be26339f726bb2aec73000e1c0dc83753829f49baac47c5f88658c67739e87"
},
"blockDaaScore": "0n",
"isCoinbase": false
},
"outpoint": {
"transactionId": "5c1ddb4494ac8eb6488808c8be89f91e76402da497182a271eaec9227a10a1ea",
"index": 0
},
"address": {
"version": "ScriptHash",
"prefix": "kaspatest",
"payload": "pz6gd03xxw0hy6aj4mrnqq8pcrwgxafc986fh2ky030csevvvaeeuysw0srlr"
},
"amount": "30000000n",
"isCoinbase": false,
"blockDaaScore": "0n",
"scriptPublicKey": {
"version": 0,
"script": "aa20b486be26339f726bb2aec73000e1c0dc83753829f49baac47c5f88658c67739e87"
}
}
}
],
"outputs": [
{
"value": "27997619n",
"scriptPublicKey": {
"version": 0,
"script": "208426329e968fbc322383543cc2f75b2a3c3aa6c1e13be66155aaee57f17c9323ac"
}
}
],
"version": 0,
"lockTime": "0n",
"gas": "0n",
"subnetworkId": "0000000000000000000000000000000000000000",
"payload": "",
"mass": "2384n"
}
}
]
34 changes: 5 additions & 29 deletions packages/coin-kaspa-rpc/tests/tx/generator-kas.test.ts
Original file line number Diff line number Diff line change
@@ -1,13 +1,6 @@
import { describe, expect, it } from 'vitest';
import {
Fees,
Generator,
GeneratorSettings,
PaymentOutput,
SignableTransaction,
UtxoEntryReference
} from '../../src/lib/tx';
import { Address, kaspaToSompi, NetworkId, NetworkType } from '../../src/lib';
import { Fees, Generator, SignableTransaction } from '../../src/lib/tx';
import { kaspaToSompi, NetworkId, NetworkType, SendKasPramas } from '../../src/lib';
import { parseTxsFromFile, parseUtxosFromFile } from './test-helper';

const SENDER_ADDR = 'kaspatest:qzzzvv57j68mcv3rsd2reshhtv4rcw4xc8snhenp2k4wu4l30jfjxlgfr8qcz';
Expand All @@ -16,9 +9,9 @@ const TESTNET_10 = new NetworkId(NetworkType.Testnet, 10);
const PRIORITY_FEES = new Fees(kaspaToSompi(0.02));

describe('Generator kas tx', () => {
const sentKas10 = new SendKasPramas(SENDER_ADDR, kaspaToSompi(10), RECEIVER_ADDR);
const send1Kas10K = new SendKasPramas(SENDER_ADDR, kaspaToSompi(10000), RECEIVER_ADDR);
const sendKas1M = new SendKasPramas(SENDER_ADDR, kaspaToSompi(1000000), RECEIVER_ADDR);
const sentKas10 = new SendKasPramas(SENDER_ADDR, kaspaToSompi(10), RECEIVER_ADDR, TESTNET_10, PRIORITY_FEES);
const send1Kas10K = new SendKasPramas(SENDER_ADDR, kaspaToSompi(10000), RECEIVER_ADDR, TESTNET_10, PRIORITY_FEES);
const sendKas1M = new SendKasPramas(SENDER_ADDR, kaspaToSompi(1000000), RECEIVER_ADDR, TESTNET_10, PRIORITY_FEES);
const testCases = [
{ name: '10 KAS', params: sentKas10 },
{ name: '10K KAS', params: send1Kas10K },
Expand Down Expand Up @@ -63,20 +56,3 @@ describe('Generator kas tx', () => {
});
}
});

class SendKasPramas {
sender: Address;
amount: bigint;
receiver: Address;

constructor(sender: string, amount: bigint, receiver: string) {
this.sender = Address.fromString(sender);
this.amount = amount;
this.receiver = Address.fromString(receiver);
}

toGeneratorSettings(uxtos: UtxoEntryReference[] = []): GeneratorSettings {
const output = new PaymentOutput(this.receiver, this.amount);
return new GeneratorSettings(output, this.sender, uxtos, TESTNET_10, PRIORITY_FEES);
}
}
Loading

0 comments on commit 67bb0c3

Please sign in to comment.