Skip to content

Commit 8afd635

Browse files
feat(sdk-coin-sui): sui sponsorship support
TICKET: WIN-6028
1 parent aeb595f commit 8afd635

File tree

4 files changed

+73
-13
lines changed

4 files changed

+73
-13
lines changed

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

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,14 +3,20 @@ import {
33
TransactionType as BitGoTransactionType,
44
} from '@bitgo/sdk-core';
55
import BigNumber from 'bignumber.js';
6-
import {
7-
CallArg,
8-
GasData,
9-
ProgrammableTransaction,
10-
SuiAddress,
11-
SuiObjectRef,
12-
TransactionExpiration,
13-
} from './mystenlab/types';
6+
import { CallArg, ProgrammableTransaction, SuiAddress, SuiObjectRef, TransactionExpiration } from './mystenlab/types';
7+
8+
export interface GasData {
9+
payment: SuiObjectRef[];
10+
owner: SuiAddress;
11+
price: number;
12+
budget: number;
13+
sponsor?: SuiAddress;
14+
}
15+
16+
export interface GasDataWithSponsor extends GasData {
17+
sponsor: SuiAddress;
18+
}
19+
1420
import { TransactionBlockInput, TransactionType } from './mystenlab/builder';
1521

1622
export enum SuiTransactionType {

modules/sdk-coin-sui/src/lib/mystenlab/builder/TransactionDataBlock.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ const GasConfig = object({
4343
price: optional(StringEncodedBigint),
4444
payment: optional(array(SuiObjectRef)),
4545
owner: optional(SuiAddress),
46+
sponsor: optional(SuiAddress),
4647
});
4748
type GasConfig = Infer<typeof GasConfig>;
4849

@@ -213,6 +214,9 @@ export class TransactionBlockDataBuilder {
213214
owner: prepareSuiAddress(this.gasConfig.owner ?? sender),
214215
price: BigInt(gasConfig.price),
215216
budget: BigInt(gasConfig.budget),
217+
...(gasConfig.sponsor && {
218+
sponsor: prepareSuiAddress(gasConfig.sponsor),
219+
}),
216220
},
217221
kind: {
218222
ProgrammableTransaction: {

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

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,10 +6,10 @@ import {
66
Signature,
77
TransactionType as BitGoTransactionType,
88
} from '@bitgo/sdk-core';
9-
import { SuiProgrammableTransaction, SuiTransaction, SuiTransactionType, TxData } from './iface';
9+
import { SuiProgrammableTransaction, SuiTransaction, SuiTransactionType, TxData, GasData } from './iface';
1010
import { BaseCoin as CoinConfig } from '@bitgo/statics';
1111
import utils, { AppId, Intent, IntentScope, IntentVersion, isImmOrOwnedObj } from './utils';
12-
import { GasData, normalizeSuiAddress, normalizeSuiObjectId, SuiObjectRef } from './mystenlab/types';
12+
import { normalizeSuiAddress, normalizeSuiObjectId, SuiObjectRef } from './mystenlab/types';
1313
import { SIGNATURE_SCHEME_BYTES } from './constants';
1414
import { Buffer } from 'buffer';
1515
import { fromB64, toB64 } from '@mysten/bcs';
@@ -178,6 +178,9 @@ export abstract class Transaction<T> extends BaseTransaction {
178178
owner: normalizeSuiAddress(transactionBlock.gasConfig.owner!),
179179
price: Number(transactionBlock.gasConfig.price as string),
180180
budget: Number(transactionBlock.gasConfig.budget as string),
181+
...(transactionBlock.gasConfig.sponsor && {
182+
sponsor: normalizeSuiAddress(transactionBlock.gasConfig.sponsor),
183+
}),
181184
},
182185
};
183186
}
@@ -213,12 +216,20 @@ export abstract class Transaction<T> extends BaseTransaction {
213216
}
214217

215218
static getProperGasData(k: any): GasData {
216-
return {
217-
payment: [this.normalizeSuiObjectRef(k.gasData.payment)],
219+
const gasData: GasData = {
220+
payment: Array.isArray(k.gasData.payment)
221+
? k.gasData.payment.map((p: any) => this.normalizeSuiObjectRef(p))
222+
: [this.normalizeSuiObjectRef(k.gasData.payment)],
218223
owner: utils.normalizeHexId(k.gasData.owner),
219224
price: Number(k.gasData.price),
220225
budget: Number(k.gasData.budget),
221226
};
227+
228+
if (k.gasData.sponsor) {
229+
gasData.sponsor = utils.normalizeHexId(k.gasData.sponsor);
230+
}
231+
232+
return gasData;
222233
}
223234

224235
private static normalizeCoins(coins: any[]): SuiObjectRef[] {

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

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ import {
4242
} from './lib';
4343
import utils from './lib/utils';
4444
import * as _ from 'lodash';
45-
import { SuiObjectInfo, SuiTransactionType } from './lib/iface';
45+
import { GasDataWithSponsor, SuiObjectInfo, SuiTransactionType } from './lib/iface';
4646
import {
4747
DEFAULT_GAS_OVERHEAD,
4848
DEFAULT_GAS_PRICE,
@@ -58,6 +58,20 @@ export interface ExplainTransactionOptions {
5858
txHex: string;
5959
}
6060

61+
export interface CreateSponsoredTransactionOptions {
62+
sender: string;
63+
sponsor: string;
64+
recipients: {
65+
address: string;
66+
amount: string;
67+
}[];
68+
gasData: {
69+
price: number;
70+
budget: number;
71+
payment: SuiObjectInfo[];
72+
};
73+
}
74+
6175
export interface SuiParseTransactionOptions extends BaseParseTransactionOptions {
6276
txHex: string;
6377
}
@@ -280,6 +294,31 @@ export class Sui extends BaseCoin {
280294
return new TransactionBuilderFactory(coins.get(this.getChain()));
281295
}
282296

297+
/**
298+
* Create a sponsored transaction where gas is paid by a different account
299+
* @param params Parameters for creating a sponsored transaction
300+
* @returns The built transaction ready for signing
301+
*/
302+
async createSponsoredTransaction(params: CreateSponsoredTransactionOptions): Promise<TransferTransaction> {
303+
const factory = this.getBuilder();
304+
const gasData: GasDataWithSponsor = {
305+
owner: params.sponsor,
306+
price: params.gasData.price,
307+
budget: params.gasData.budget,
308+
payment: params.gasData.payment,
309+
sponsor: params.sponsor,
310+
};
311+
312+
const txBuilder = factory
313+
.getTransferBuilder()
314+
.type(SuiTransactionType.Transfer)
315+
.sender(params.sender)
316+
.send(params.recipients)
317+
.gasData(gasData);
318+
319+
return (await txBuilder.build()) as TransferTransaction;
320+
}
321+
283322
private getAddressFromPublicKey(derivedPublicKey: string) {
284323
// TODO(BG-59016) replace with account lib implementation
285324
return utils.getAddressFromPublicKey(derivedPublicKey);

0 commit comments

Comments
 (0)