Skip to content

Commit

Permalink
refactor: enable multipayments with mainsail (#47)
Browse files Browse the repository at this point in the history
  • Loading branch information
goga-m authored Apr 3, 2024
1 parent c2edf07 commit 9dc4c5f
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 13 deletions.
1 change: 1 addition & 0 deletions packages/mainsail/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@
"@mainsail/crypto-key-pair-ecdsa": "0.0.1-alpha.13",
"@mainsail/crypto-signature-schnorr-secp256k1": "0.0.1-alpha.13",
"@mainsail/crypto-transaction": "0.0.1-alpha.13",
"@mainsail/crypto-transaction-multi-payment": "0.0.1-alpha.13",
"@mainsail/crypto-transaction-transfer": "0.0.1-alpha.13",
"@mainsail/crypto-validation": "0.0.1-alpha.13",
"@mainsail/fees": "0.0.1-alpha.13",
Expand Down
2 changes: 1 addition & 1 deletion packages/mainsail/source/client.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ export class ClientService extends Services.AbstractClientService {
// @TODO: For the moment only transfer transactions are sent to the
// `transaction-pool` once rest of the transaction types are supported
// we are likely send all of them to the same endpoint.
const isTransfer = transactions.some((t) => t.isTransfer());
const isTransfer = transactions.some((t) => t.isTransfer() || t.isMultiPayment());
const endpointUrl = isTransfer ? "transaction-pool" : "transactions";
const networkHostyType = isTransfer ? "tx" : "full";

Expand Down
52 changes: 40 additions & 12 deletions packages/mainsail/source/transaction.service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,11 @@ import {
ServiceProvider as CoreCryptoTransactionTransfer,
TransferBuilder,
} from "@mainsail/crypto-transaction-transfer";

import {
ServiceProvider as CoreCryptoMultipaymentTransfer,
MultiPaymentBuilder,
} from "@mainsail/crypto-transaction-multi-payment";
import { Container } from "@mainsail/container";

import { milestones } from "./crypto/networks/devnet/milestones.js";
Expand Down Expand Up @@ -77,13 +82,14 @@ export class TransactionService extends Services.AbstractTransactionService {
this.#app.resolve(CoreFeesStatic).register(),
this.#app.resolve(CoreCryptoTransaction).register(),
this.#app.resolve(CoreCryptoTransactionTransfer).register(),
this.#app.resolve(CoreCryptoMultipaymentTransfer).register(),
]);

this.#app
.get<{
setConfig: Function;
}>(Identifiers.Cryptography.Configuration)
.setConfig({ milestones, network });
.setConfig({ network, milestones });

this.#isBooted = true;
}
Expand All @@ -96,10 +102,6 @@ export class TransactionService extends Services.AbstractTransactionService {
* @ledgerS
*/
public override async transfer(input: Services.TransferInput): Promise<Contracts.SignedTransactionData> {
if (!this.#isBooted) {
await this.#boot();
}

return this.#createTransferFromData(input, ({ transaction, data }) => {
transaction.recipientId(data.to);

Expand Down Expand Up @@ -209,15 +211,38 @@ export class TransactionService extends Services.AbstractTransactionService {
* @musig
*/
public override async multiPayment(input: Services.MultiPaymentInput): Promise<Contracts.SignedTransactionData> {
return this.#createFromData("multiPayment", input, ({ transaction, data }) => {
for (const payment of data.payments) {
transaction.addPayment(payment.to, this.toSatoshi(payment.amount).toString());
}
if (!this.#isBooted) {
await this.#boot();
}

if (data.memo) {
transaction.vendorField(data.memo);
}
const transactionWallet = await this.clientService.wallet({
type: "address",
value: input.signatory.address(),
});

let builder = this.#app.resolve(MultiPaymentBuilder).nonce(transactionWallet.nonce().plus(1).toFixed(0));

if (input.fee) {
builder = builder.fee(this.toSatoshi(input.fee).toString());
}

if (input.data.memo) {
builder.vendorField(input.data.memo);
}

for (const { amount, to } of input.data.payments) {
builder = builder.addPayment(to, BigNumber.make(this.toSatoshi(amount)).toString());
}

const signedTransactionBuilder = await builder.sign(input.signatory.signingKey());

const signedTransaction = await signedTransactionBuilder.build();

return this.dataTransferObjectService.signedTransaction(
signedTransaction.id!,
signedTransaction.data,
signedTransaction.serialized.toString("hex"),
);
}

public override async delegateResignation(
Expand Down Expand Up @@ -400,6 +425,9 @@ export class TransactionService extends Services.AbstractTransactionService {
input: Services.TransferInput,
callback?: Function,
): Promise<Contracts.SignedTransactionData> {
if (!this.#isBooted) {
await this.#boot();
}
applyCryptoConfiguration(this.#configCrypto);

// @TODO: update `TransferInput` definition globally once everything
Expand Down
18 changes: 18 additions & 0 deletions pnpm-lock.yaml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

0 comments on commit 9dc4c5f

Please sign in to comment.