Skip to content

Commit ee3b648

Browse files
Merge pull request #5453 from BitGo/ben/SC-996-wal-sdk-stake
feat(wal): walrus staking transaction builder
2 parents fa245c4 + 8ffdaf0 commit ee3b648

File tree

9 files changed

+783
-2
lines changed

9 files changed

+783
-2
lines changed

modules/sdk-coin-sui/src/lib/iface.ts

Lines changed: 21 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@ export enum SuiTransactionType {
1919
WithdrawStake = 'WithdrawStake',
2020
CustomTx = 'CustomTx',
2121
TokenTransfer = 'TokenTransfer',
22+
WalrusStakeWithPool = 'WalrusStakeWithPool',
2223
}
2324

2425
export interface TransactionExplanation extends BaseTransactionExplanation {
@@ -30,7 +31,8 @@ export type SuiProgrammableTransaction =
3031
| StakingProgrammableTransaction
3132
| UnstakingProgrammableTransaction
3233
| CustomProgrammableTransaction
33-
| TokenTransferProgrammableTransaction;
34+
| TokenTransferProgrammableTransaction
35+
| WalrusStakingProgrammableTransaction;
3436

3537
export interface TxData {
3638
id?: string;
@@ -78,6 +80,13 @@ export type TokenTransferProgrammableTransaction =
7880
transactions: TransactionType[];
7981
};
8082

83+
export type WalrusStakingProgrammableTransaction =
84+
| ProgrammableTransaction
85+
| {
86+
inputs: CallArg[] | TransactionBlockInput[];
87+
transactions: TransactionType[];
88+
};
89+
8190
export interface SuiTransaction<T = SuiProgrammableTransaction> {
8291
id?: string;
8392
type: SuiTransactionType;
@@ -96,6 +105,11 @@ export interface RequestWithdrawStakedSui {
96105
stakedSui: SuiObjectRef;
97106
}
98107

108+
export interface RequestWalrusStakeWithPool {
109+
amount: number;
110+
validatorAddress: SuiAddress;
111+
}
112+
99113
/**
100114
* Method names for the transaction method. Names change based on the type of transaction e.g 'request_add_delegation_mul_coin' for the staking transaction
101115
*/
@@ -124,6 +138,12 @@ export enum MethodNames {
124138
* @see https://github.com/MystenLabs/sui/blob/main/crates/sui-framework/docs/transfer.md#function-public_transfer
125139
*/
126140
PublicTransfer = '::transfer::public_transfer',
141+
/**
142+
* Walrus stake with pool.
143+
*
144+
* @see https://github.com/MystenLabs/walrus-docs/blob/8ba15d67d7ed0e728077e1600866fddd46fd113b/contracts/walrus/sources/staking.move#L289
145+
*/
146+
WalrusStakeWithPool = 'stake_with_pool',
127147
}
128148

129149
export interface SuiObjectInfo extends SuiObjectRef {
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
import { SharedObjectRef } from '../mystenlab/types';
2+
3+
export const WALRUS_TESTNET_CONFIG = {
4+
WALRUS_SYSTEM_OBJECT: {
5+
objectId: '0x98ebc47370603fe81d9e15491b2f1443d619d1dab720d586e429ed233e1255c1',
6+
initialSharedVersion: 1,
7+
mutable: true,
8+
} as SharedObjectRef,
9+
10+
WALRUS_STAKING_OBJECT: {
11+
objectId: '0x20266a17b4f1a216727f3eef5772f8d486a9e3b5e319af80a5b75809c035561d',
12+
initialSharedVersion: 334023834,
13+
mutable: true,
14+
} as SharedObjectRef,
15+
16+
WALRUS_PKG_ID: '0x795ddbc26b8cfff2551f45e198b87fc19473f2df50f995376b924ac80e56f88b',
17+
WALRUS_STAKING_MODULE_NAME: 'staking',
18+
WALRUS_STAKE_WITH_POOL_FUN_NAME: 'stake_with_pool',
19+
20+
WAL_PKG_ID: '0x8190b041122eb492bf63cb464476bd68c6b7e570a4079645a8b28732b6197a82',
21+
WAL_COIN_MODULE_NAME: 'wal',
22+
WAL_COIN_NAME: 'WAL',
23+
};
24+
25+
export const WALRUS_PROD_CONFIG = {
26+
...WALRUS_TESTNET_CONFIG,
27+
28+
WALRUS_SYSTEM_OBJECT: {
29+
objectId: 'TODO PROD CONFIG',
30+
initialSharedVersion: 1,
31+
mutable: true,
32+
} as SharedObjectRef,
33+
34+
WALRUS_STAKING_OBJECT: {
35+
objectId: 'TODO PROD CONFIG',
36+
initialSharedVersion: 0, // TODO PROD CONFIG
37+
mutable: true,
38+
} as SharedObjectRef,
39+
40+
WALRUS_PKG_ID: 'TODO PROD CONFIG',
41+
WAL_PKG_ID: 'TODO PROD CONFIG',
42+
};

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

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -187,6 +187,9 @@ export abstract class Transaction<T> extends BaseTransaction {
187187
if (transactions.length == 1) {
188188
return utils.getSuiTransactionType(transactions[0]);
189189
}
190+
if (transactions.some((tx) => utils.getSuiTransactionType(tx) === SuiTransactionType.WalrusStakeWithPool)) {
191+
return SuiTransactionType.WalrusStakeWithPool;
192+
}
190193
if (transactions.some((tx) => utils.getSuiTransactionType(tx) === SuiTransactionType.AddStake)) {
191194
return SuiTransactionType.AddStake;
192195
}

modules/sdk-coin-sui/src/lib/transactionBuilderFactory.ts

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import {
1212
UnstakingProgrammableTransaction,
1313
SuiProgrammableTransaction,
1414
TokenTransferProgrammableTransaction,
15+
WalrusStakingProgrammableTransaction,
1516
} from './iface';
1617
import { StakingTransaction } from './stakingTransaction';
1718
import { TransferTransaction } from './transferTransaction';
@@ -23,6 +24,8 @@ import { CustomTransaction } from './customTransaction';
2324
import { CustomTransactionBuilder } from './customTransactionBuilder';
2425
import { TokenTransferBuilder } from './tokenTransferBuilder';
2526
import { TokenTransferTransaction } from './tokenTransferTransaction';
27+
import { WalrusStakingBuilder } from './walrusStakingBuilder';
28+
import { WalrusStakingTransaction } from './walrusStakingTransaction';
2629

2730
export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
2831
constructor(_coinConfig: Readonly<CoinConfig>) {
@@ -55,6 +58,10 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
5558
const tokenTransferTx = new TokenTransferTransaction(this._coinConfig);
5659
tokenTransferTx.fromRawTransaction(raw);
5760
return this.getTokenTransferBuilder(tokenTransferTx);
61+
case SuiTransactionType.WalrusStakeWithPool:
62+
const walrusStakeTx = new WalrusStakingTransaction(this._coinConfig);
63+
walrusStakeTx.fromRawTransaction(raw);
64+
return this.getWalrusStakingBuilder(walrusStakeTx);
5865
default:
5966
throw new InvalidTransactionError('Invalid transaction');
6067
}
@@ -88,6 +95,11 @@ export class TransactionBuilderFactory extends BaseTransactionBuilderFactory {
8895
return this.initializeBuilder(tx, new TokenTransferBuilder(this._coinConfig));
8996
}
9097

98+
/** @inheritdoc */
99+
getWalrusStakingBuilder(tx?: Transaction<WalrusStakingProgrammableTransaction>): WalrusStakingBuilder {
100+
return this.initializeBuilder(tx, new WalrusStakingBuilder(this._coinConfig));
101+
}
102+
91103
/** @inheritdoc */
92104
getWalletInitializationBuilder(): void {
93105
throw new Error('Method not implemented.');

modules/sdk-coin-sui/src/lib/utils.ts

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@ import { BCS, fromB64 } from '@mysten/bcs';
1414
import {
1515
MethodNames,
1616
RequestAddStake,
17+
RequestWalrusStakeWithPool,
1718
StakingProgrammableTransaction,
19+
WalrusStakingProgrammableTransaction,
1820
SuiObjectInfo,
1921
SuiProgrammableTransaction,
2022
SuiTransaction,
@@ -195,6 +197,7 @@ export class Utils implements BaseUtils {
195197
case SuiTransactionType.TokenTransfer:
196198
return TransactionType.Send;
197199
case SuiTransactionType.AddStake:
200+
case SuiTransactionType.WalrusStakeWithPool:
198201
return TransactionType.StakingAdd;
199202
case SuiTransactionType.WithdrawStake:
200203
return TransactionType.StakingWithdraw;
@@ -233,6 +236,8 @@ export class Utils implements BaseUtils {
233236
command.target.endsWith(MethodNames.PublicTransfer)
234237
) {
235238
return SuiTransactionType.CustomTx;
239+
} else if (command.target.endsWith(MethodNames.WalrusStakeWithPool)) {
240+
return SuiTransactionType.WalrusStakeWithPool;
236241
} else {
237242
throw new InvalidTransactionError(`unsupported target method ${command.target}`);
238243
}
@@ -327,6 +332,29 @@ export class Utils implements BaseUtils {
327332
});
328333
}
329334

335+
getWalrusStakeWithPoolRequests(tx: WalrusStakingProgrammableTransaction): RequestWalrusStakeWithPool[] {
336+
const amounts: number[] = [];
337+
const addresses: string[] = [];
338+
tx.transactions.forEach((transaction, i) => {
339+
if (transaction.kind === 'SplitCoins') {
340+
const amountInputIdx = ((transaction as SplitCoinsTransaction).amounts[0] as TransactionBlockInput).index;
341+
amounts.push(utils.getAmount(tx.inputs[amountInputIdx] as TransactionBlockInput));
342+
}
343+
if (transaction.kind === 'MoveCall') {
344+
const validatorAddressInputIdx = ((transaction as MoveCallTransaction).arguments[2] as TransactionBlockInput)
345+
.index;
346+
const validatorAddress = utils.getAddress(tx.inputs[validatorAddressInputIdx] as TransactionBlockInput);
347+
addresses.push(validatorAddress);
348+
}
349+
});
350+
return addresses.map((address, index) => {
351+
return {
352+
validatorAddress: address,
353+
amount: amounts[index],
354+
} as RequestWalrusStakeWithPool;
355+
});
356+
}
357+
330358
getAmount(input: SuiJsonValue | TransactionBlockInput): number {
331359
return isPureArg(input)
332360
? builder.de(BCS.U64, Buffer.from(new Uint16Array(input.Pure)).toString('base64'), 'base64')

0 commit comments

Comments
 (0)