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

[ts sdk] Add global registry for transaction plugins #18928

Merged
merged 2 commits into from
Aug 19, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 5 additions & 0 deletions .changeset/witty-wombats-study.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@mysten/sui': minor
---

Add global registry for transaction plugins
41 changes: 39 additions & 2 deletions sdk/typescript/src/transactions/Transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -98,12 +98,38 @@ export function isTransaction(obj: unknown): obj is Transaction {

export type TransactionObjectInput = string | CallArg | TransactionObjectArgument;

const TRANSACTION_REGISTRY_KEY = Symbol.for('@mysten/transaction/registry');
function getGlobalPluginRegistry() {
try {
const target = globalThis as {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Excited for however this will accidentally break things! 😆

[TRANSACTION_REGISTRY_KEY]?: {
buildPlugins: TransactionPlugin[];
serializationPlugins: TransactionPlugin[];
};
};

if (!target[TRANSACTION_REGISTRY_KEY]) {
target[TRANSACTION_REGISTRY_KEY] = {
buildPlugins: [],
serializationPlugins: [],
};
}

return target[TRANSACTION_REGISTRY_KEY];
} catch (e) {
return {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Could this be a module-level variable instead as the fallback so that it's at least consistent between function calls here?

buildPlugins: [],
serializationPlugins: [],
};
}
}

/**
* Transaction Builder
*/
export class Transaction {
#serializationPlugins: TransactionPlugin[] = [];
#buildPlugins: TransactionPlugin[] = [];
#serializationPlugins: TransactionPlugin[];
#buildPlugins: TransactionPlugin[];
#intentResolvers = new Map<string, TransactionPlugin>();

/**
Expand Down Expand Up @@ -142,6 +168,14 @@ export class Transaction {
return newTransaction;
}

static registerGlobalSerializationPlugin(step: TransactionPlugin) {
getGlobalPluginRegistry().serializationPlugins.push(step);
}

static registerGlobalBuildPlugin(step: TransactionPlugin) {
getGlobalPluginRegistry().buildPlugins.push(step);
}

addSerializationPlugin(step: TransactionPlugin) {
this.#serializationPlugins.push(step);
}
Expand Down Expand Up @@ -241,7 +275,10 @@ export class Transaction {
}

constructor() {
const globalPlugins = getGlobalPluginRegistry();
this.#data = new TransactionDataBuilder();
this.#buildPlugins = [...globalPlugins.buildPlugins];
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is fine to me but I do wonder if we should lazy resolve these via getters instead of during transaction construction.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

this is a good question... I went back and forth on this. I went with this way because I wasn't sure if it would be expected that transactions get new plugins after they are created.

Specifically, you could build a transaction multiple times and have it run a different set of plugins if they are added after between builds, which seemed a bit off. But I can also see why that might be desirable.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah I buy that argument. We can always change this at some point if it ends up being unintuitive anyway

this.#serializationPlugins = [...globalPlugins.serializationPlugins];
}

/** Returns an argument for the gas coin, to be used in a transaction. */
Expand Down
Loading