Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

refactor: enable multipayments with mainsail #47

Merged
merged 16 commits into from
Apr 3, 2024
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(amount).toString());
ItsANameToo marked this conversation as resolved.
Show resolved Hide resolved
}

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.

Loading