Skip to content

Commit c42cc74

Browse files
authored
Merge pull request #6091 from BitGo/WIN-5244
feat(sdk-coin-polyx): add transaction builders
2 parents 0f9d886 + 31c96bb commit c42cc74

27 files changed

+962
-198
lines changed

modules/abstract-substrate/src/lib/iface.ts

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,8 +31,22 @@ export enum MethodNames {
3131
* @see https://polkadot.js.org/docs/substrate/extrinsics/#transferkeepalivedest-multiaddress-value-compactu128
3232
*/
3333
TransferKeepAlive = 'transferKeepAlive',
34+
/**
35+
* Transfer funds with an optional memo attached.
36+
* The memo allows adding context or metadata to the transaction, commonly used for recordkeeping or identification.
37+
*
38+
* @see https://developers.polymesh.network/sdk-docs/enums/Generated/Types/BalancesTx/#transferwithmemo
39+
*/
40+
TransferWithMemo = 'transferWithMemo',
3441
AddStake = 'addStake',
3542
RemoveStake = 'removeStake',
43+
44+
/**
45+
* Registers a Decentralized Identifier (DID) along with Customer Due Diligence (CDD) information.
46+
*
47+
* @see https://developers.polymesh.network/sdk-docs/enums/Generated/Types/IdentityTx/#cddregisterdidwithcdd
48+
*/
49+
RegisterDidWithCDD = 'cddRegisterDidWithCdd',
3650
}
3751

3852
/**
@@ -75,6 +89,12 @@ export interface TransferAllArgs {
7589
keepAlive: boolean;
7690
}
7791

92+
export interface TransferWithMemoArgs extends Args {
93+
dest: { id: string };
94+
value: string;
95+
memo: string;
96+
}
97+
7898
export interface AddStakeArgs extends Args {
7999
amountStaked: string;
80100
hotkey: string;

modules/abstract-substrate/src/lib/txnSchema.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,12 @@ export const TransferAllTransactionSchema = joi.object({
4040
to: addressSchema.required(),
4141
});
4242

43+
export const TransferWithMemoTransactionSchema = joi.object({
44+
amount: joi.string().required(),
45+
to: addressSchema.required(),
46+
memo: joi.string().required(),
47+
});
48+
4349
export const StakeTransactionSchema = joi.object({
4450
amountStaked: joi.string().required(),
4551
hotkey: joi.string().required(),

modules/sdk-coin-polyx/package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -41,9 +41,12 @@
4141
},
4242
"dependencies": {
4343
"@bitgo/abstract-substrate": "^1.4.8",
44+
"@substrate/txwrapper-core": "7.5.2",
45+
"@substrate/txwrapper-polkadot": "7.5.2",
4446
"@bitgo/sdk-core": "^33.1.0",
4547
"@bitgo/statics": "^52.1.0",
46-
"bignumber.js": "^9.1.2"
48+
"bignumber.js": "^9.1.2",
49+
"joi": "^17.4.0"
4750
},
4851
"devDependencies": {
4952
"@bitgo/sdk-api": "^1.62.2",
Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
1-
/**
2-
* The transaction data returned from the toJson() function of a transaction
3-
*/
4-
export interface TxData {
5-
id: string;
1+
import { Args } from '@substrate/txwrapper-core';
2+
3+
export interface RegisterDidWithCDDArgs extends Args {
4+
targetAccount: string;
5+
secondaryKeys: [];
6+
expiry: null;
67
}
Lines changed: 12 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
1-
import * as Utils from './utils';
2-
import * as Interface from './iface';
1+
export {
2+
Constants,
3+
Errors,
4+
Interface,
5+
KeyPair,
6+
SingletonRegistry,
7+
Transaction,
8+
TransactionBuilder,
9+
} from '@bitgo/abstract-substrate';
310

4-
export { KeyPair } from './keyPair';
5-
export { Transaction } from './transaction';
6-
export { TransactionBuilder } from './transactionBuilder';
7-
export { TransferBuilder } from './transferBuilder';
811
export { TransactionBuilderFactory } from './transactionBuilderFactory';
9-
export { Interface, Utils };
12+
export { TransferBuilder } from './transferBuilder';
13+
export { RegisterDidWithCDDBuilder } from './registerDidWithCDDBuilder';
14+
export { Utils, default as utils } from './utils';

modules/sdk-coin-polyx/src/lib/keyPair.ts

Lines changed: 0 additions & 23 deletions
This file was deleted.
Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
import { TransactionBuilder, Interface } from '@bitgo/abstract-substrate';
2+
import { DecodedSignedTx, DecodedSigningPayload, defineMethod, UnsignedTransaction } from '@substrate/txwrapper-core';
3+
import { BaseCoin as CoinConfig } from '@bitgo/statics';
4+
import { TransactionType, BaseAddress, InvalidTransactionError } from '@bitgo/sdk-core';
5+
import { RegisterDidWithCDDArgs } from './iface';
6+
import { RegisterDidWithCDDTransactionSchema } from './txnSchema';
7+
8+
export class RegisterDidWithCDDBuilder extends TransactionBuilder {
9+
protected _to: string;
10+
11+
constructor(_coinConfig: Readonly<CoinConfig>) {
12+
super(_coinConfig);
13+
}
14+
15+
protected get transactionType(): TransactionType {
16+
return TransactionType.WalletInitialization;
17+
}
18+
19+
protected buildTransaction(): UnsignedTransaction {
20+
const baseTxInfo = this.createBaseTxInfo();
21+
return this.RegisterDidWithCDD(
22+
{
23+
targetAccount: this._to,
24+
secondaryKeys: [],
25+
expiry: null,
26+
},
27+
baseTxInfo
28+
);
29+
}
30+
31+
/**
32+
*
33+
* The destination address for transfer transaction.
34+
*
35+
* @param {string} dest
36+
* @returns {TransferBuilder} This transfer builder.
37+
*/
38+
to({ address }: BaseAddress): this {
39+
this.validateAddress({ address });
40+
this._to = address;
41+
return this;
42+
}
43+
44+
/** @inheritdoc */
45+
validateDecodedTransaction(decodedTxn: DecodedSigningPayload | DecodedSignedTx, rawTransaction?: string): void {
46+
if (decodedTxn.method?.name === Interface.MethodNames.RegisterDidWithCDD) {
47+
const txMethod = decodedTxn.method.args as RegisterDidWithCDDArgs;
48+
const targetAccount = txMethod.targetAccount;
49+
const secondaryKeys = txMethod.secondaryKeys;
50+
const expiry = txMethod.expiry;
51+
52+
const validationResult = RegisterDidWithCDDTransactionSchema.validate({ targetAccount, secondaryKeys, expiry });
53+
if (validationResult.error) {
54+
throw new InvalidTransactionError(`Invalid transaction: ${validationResult.error.message}`);
55+
}
56+
}
57+
}
58+
59+
/**
60+
* Construct a transaction to register a DID with CDD information
61+
*
62+
* @param {RegisterDidWithCDDArgs} args Arguments to be passed to the cddRegisterDidWithCdd method
63+
* @param {Interface.CreateBaseTxInfo} info Base txn info required to construct the DID registration txn
64+
* @returns {UnsignedTransaction} an unsigned transaction for DID registration with CDD
65+
*/
66+
private RegisterDidWithCDD(args: RegisterDidWithCDDArgs, info: Interface.CreateBaseTxInfo): UnsignedTransaction {
67+
return defineMethod(
68+
{
69+
method: {
70+
args,
71+
name: 'cddRegisterDidWithCdd',
72+
pallet: 'identity',
73+
},
74+
...info.baseTxInfo,
75+
},
76+
info.options
77+
);
78+
}
79+
}

modules/sdk-coin-polyx/src/lib/transaction.ts

Lines changed: 0 additions & 16 deletions
This file was deleted.

modules/sdk-coin-polyx/src/lib/transactionBuilder.ts

Lines changed: 0 additions & 99 deletions
This file was deleted.
Lines changed: 45 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,20 +1,56 @@
1-
import { BaseTransactionBuilderFactory } from '@bitgo/sdk-core';
2-
import { TransactionBuilder } from './transactionBuilder';
1+
import { BaseTransactionBuilderFactory, NotImplementedError } from '@bitgo/sdk-core';
2+
import { BaseCoin as CoinConfig } from '@bitgo/statics';
3+
import { decode } from '@substrate/txwrapper-polkadot';
34
import { TransferBuilder } from './transferBuilder';
5+
import { RegisterDidWithCDDBuilder } from './registerDidWithCDDBuilder';
6+
import utils from './utils';
7+
import { Interface, SingletonRegistry, TransactionBuilder } from './';
48

59
export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
6-
/** @inheritdoc */
7-
from(raw: string): TransactionBuilder {
8-
throw new Error('Method not implemented.');
10+
protected _material: Interface.Material;
11+
12+
constructor(_coinConfig: Readonly<CoinConfig>) {
13+
super(_coinConfig);
14+
this._material = utils.getMaterial(_coinConfig.network.type);
915
}
1016

11-
/** @inheritdoc */
1217
getTransferBuilder(): TransferBuilder {
13-
throw new Error('Method not implemented.');
18+
return new TransferBuilder(this._coinConfig).material(this._material);
19+
}
20+
21+
getRegisterDidWithCDDBuilder(): RegisterDidWithCDDBuilder {
22+
return new RegisterDidWithCDDBuilder(this._coinConfig).material(this._material);
1423
}
1524

16-
/** @inheritdoc */
1725
getWalletInitializationBuilder(): void {
18-
throw new Error('Method not implemented.');
26+
throw new NotImplementedError(`walletInitialization for ${this._coinConfig.name} not implemented`);
27+
}
28+
29+
from(rawTxn: string): TransactionBuilder {
30+
const builder = this.getBuilder(rawTxn);
31+
builder.from(rawTxn);
32+
return builder;
33+
}
34+
35+
material(material: Interface.Material): this {
36+
this._material = material;
37+
return this;
38+
}
39+
40+
private getBuilder(rawTxn: string): TransactionBuilder {
41+
const registry = SingletonRegistry.getInstance(this._material);
42+
const decodedTxn = decode(rawTxn, {
43+
metadataRpc: this._material.metadata,
44+
registry: registry,
45+
});
46+
47+
const methodName = decodedTxn.method?.name;
48+
if (methodName === Interface.MethodNames.TransferWithMemo) {
49+
return this.getTransferBuilder();
50+
} else if (methodName === Interface.MethodNames.RegisterDidWithCDD) {
51+
return this.getRegisterDidWithCDDBuilder();
52+
} else {
53+
throw new Error('Transaction cannot be parsed or has an unsupported transaction type');
54+
}
1955
}
2056
}

0 commit comments

Comments
 (0)