-
Notifications
You must be signed in to change notification settings - Fork 17
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
Add support for Preview 10 operations when assembling Soroban transactions. #108
Changes from 7 commits
1af6c87
c597f01
e638d1b
8a72fd6
2d3e12e
25fb2a1
2f0c596
ea8ccb3
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,31 +13,29 @@ import { SorobanRpc } from "./soroban_rpc"; | |
export function assembleTransaction( | ||
raw: Transaction | FeeBumpTransaction, | ||
networkPassphrase: string, | ||
simulation: SorobanRpc.SimulateTransactionResponse, | ||
simulation: SorobanRpc.SimulateTransactionResponse | ||
): Transaction { | ||
if ("innerTransaction" in raw) { | ||
// TODO: Handle feebump transactions | ||
return assembleTransaction( | ||
raw.innerTransaction, | ||
networkPassphrase, | ||
simulation, | ||
simulation | ||
); | ||
} | ||
|
||
if ( | ||
raw.operations.length !== 1 || | ||
raw.operations[0].type !== "invokeHostFunction" | ||
) { | ||
throw new Error( | ||
"unsupported operation type, must be only one InvokeHostFunctionOp in the transaction.", | ||
if (!isSorobanTransaction(raw)) { | ||
throw new TypeError( | ||
"unsupported transaction: must contain exactly one " + | ||
"invokeHostFunction, bumpFootprintExpiration, or restoreFootprint " + | ||
"operation" | ||
); | ||
} | ||
|
||
if (simulation.results.length !== 1) { | ||
throw new Error(`simulation results invalid: ${simulation.results}`); | ||
} | ||
|
||
|
||
const source = new Account(raw.source, `${parseInt(raw.sequence, 10) - 1}`); | ||
const classicFeeNum = parseInt(raw.fee, 10) || 0; | ||
const minResourceFeeNum = parseInt(simulation.minResourceFee, 10) || 0; | ||
|
@@ -61,25 +59,63 @@ export function assembleTransaction( | |
extraSigners: raw.extraSigners, | ||
}); | ||
|
||
// apply the auth from the simulation to the invokeHostFunction op's props | ||
const invokeOp: Operation.InvokeHostFunction = raw.operations[0]; | ||
txnBuilder.addOperation( | ||
Operation.invokeHostFunction({ | ||
func: invokeOp.func, | ||
auth: (invokeOp.auth ?? []).concat( | ||
simulation.results[0].auth?.map((a: string) => | ||
xdr.SorobanAuthorizationEntry.fromXDR(a, "base64") | ||
) ?? [] | ||
), | ||
}) | ||
); | ||
switch (raw.operations[0].type) { | ||
case "invokeHostFunction": | ||
const invokeOp: Operation.InvokeHostFunction = raw.operations[0]; | ||
txnBuilder.addOperation( | ||
Operation.invokeHostFunction({ | ||
source: invokeOp.source, | ||
func: invokeOp.func, | ||
// apply the auth from the simulation | ||
auth: (invokeOp.auth ?? []).concat( | ||
simulation.results[0].auth?.map((a: string) => | ||
xdr.SorobanAuthorizationEntry.fromXDR(a, "base64") | ||
) ?? [] | ||
), | ||
}) | ||
); | ||
break; | ||
|
||
case "bumpFootprintExpiration": | ||
const bumpOp: Operation.BumpFootprintExpiration = raw.operations[0]; | ||
txnBuilder.addOperation( | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. since this and restore case are not merging any data from simulation, can it reduce to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I thought so, too, but kept getting some TypeScript errors... tried it again in ea8ccb3 and it worked 🤦 Great call, thank you! |
||
Operation.bumpFootprintExpiration({ | ||
source: bumpOp.source, | ||
ledgersToExpire: bumpOp.ledgersToExpire, | ||
}) | ||
); | ||
break; | ||
|
||
case "restoreFootprint": | ||
const restoreOp: Operation.RestoreFootprint = raw.operations[0]; | ||
txnBuilder.addOperation( | ||
Operation.restoreFootprint({ source: restoreOp.source }) | ||
); | ||
break; | ||
} | ||
|
||
// apply the pre-built Soroban Tx Data from simulation onto the Tx | ||
const sorobanTxData = xdr.SorobanTransactionData.fromXDR( | ||
simulation.transactionData, | ||
"base64", | ||
"base64" | ||
); | ||
txnBuilder.setSorobanData(sorobanTxData); | ||
|
||
return txnBuilder.build(); | ||
} | ||
} | ||
|
||
function isSorobanTransaction(tx: Transaction): boolean { | ||
if (tx.operations.length !== 1) { | ||
return false; | ||
} | ||
|
||
switch (tx.operations[0].type) { | ||
case "invokeHostFunction": | ||
case "bumpFootprintExpiration": | ||
case "restoreFootprint": | ||
return true; | ||
|
||
default: | ||
return false; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
note that previously we weren't copying the source