In the previous announcement about the upcoming changes for Protocol 22, we made a significant oversight in compatibility. When a user upgrades to the latest version of your SDK, their code will now only be compatible with a v22.* version of the backend services they're connected to. This means they can only upgrade exactly when their RPC/Horizon provider upgrades, which is a violation of the previous compatibility guarantees we provide the ecosystem. That guideline essentially boils down to:
You can safely upgrade your SDK prior to the next major version upgrade.
To maintain this principle, we are releasing new release candidates of Horizon and Stellar RPC to increase the backwards-compatibility of various interfaces and make it easier for people to have a smooth upgrade. We are also asking SDK maintainers to use these new, smoother interfaces to ensure that users can upgrade to the latest version of their SDKs without requiring their use exclusively with Protocol 22-compatible software. In other words, users should be able to upgrade today and not rely on v22 versions of Horizon or RPC deployed for their dependent network.
In this release, we are reintroducing fields that previously constituted breaking changes:
Previously, in RC2, getTransactions would encode createdAt as a string instead of number. This change has been reverted. The next release will continue to encode it as a number (specifically, a uint32).
Previously, getVersionInfo would now use camelCasing over snake_case. This change is now additive. The response schema in the next release will contains both variants:
Previously, getEvents replaced pagingToken with cursor within each event for pagination. This change is now additive, and the response schema will now include both fields. Please note that the id field will continue to match both the old pagingToken and the new cursor.
Previously, simulateTransaction removed the deprecated cost field. This change remains, because it does not require a "lockstep" upgrade with their provider: users can acquire the new costs by extracting them from the transaction resource data. For example,
// before:
let result = await server.simulateTranasction(tx);
// assume result.error === undefined
let cost: rpc.Api.Cost = result.cost;
// after:
let resources = result.transactionData.build().resources();
let cost: rpc.Api.Cost = {
cpuInsns: resources.instructions().toString(),
memBytes: (resources.readBytes() + resources.writeBytes()).toString(),
};
5. Previously, the `getLedgerEntry` endpoint had been removed entirely. **This change remains,** because clients can transition to `getLedgerEntries` without waiting on a provider upgrade. For example,
```bash
# before, the JSON-RPC request would have
{
# ...
"method": "getLedgerEntry",
"params": {
"key": "insert base64 xdr here"
}
}
# now it will have
{
# ...
"method": "getLedgerEntries",
"params": {
"keys": [ "insert base64 xdr here" ]
}
}
Similarly, we are reintroducing fields that previously constituted breaking changes:
Previously, the /transaction_async endpoint changed errorResultXdr :arrow_right: error_result_xdr. This change is now additive, and in the next release the response schema will have both fields.
Previously, the /asset endpoint dropped num_accounts and amount, and the /transactions/:id endpoint dropped valid_before and valid_after. These changes remain, because the values still exist in other locations. Namely, num_accounts and amount are inside of accounts, while valid_before and valid_after are equivalent to the values in the preconditions object.
Maintainer Actions
Please ensure that users can upgrade to your latest SDK version without depending exclusively on the breaking schemas in Horizon v22.0.0-rc1 and Stellar RPC v22.0.0-rc2. Users should be able to upgrade today and not rely on v22 versions of Horizon or RPC deployed for their dependent network.
Please release your Protocol-22 compatible software releases as release candidates, because things are still subject to change.
As outlined above, breaking changes are still acceptable if there is an alternative, client-side way of acquiring the same field but not if the field is only present in a v22 version of the backend service. These are part of the natural transition to a new version that clients should be prepared for.
A concrete example: someone with an existing codebase may have code written that uses the createdAt field returned by rpc.getTransaction. If they upgrade to the latest version, their code will break because the field is now strictly typed as a string. And yet, if they were to update their code accordingly, their code would not function unless they pointed at a v22 RPC. This is the lockstep upgrade we are trying to avoid. This is in contrast to a change like cost being removed, because they can write code that works on both v21 and v22 RPCs by using the existing transactionData field to migrate.
Protocol 22: Additional Changes
Interface Compatibility
In the previous announcement about the upcoming changes for Protocol 22, we made a significant oversight in compatibility. When a user upgrades to the latest version of your SDK, their code will now only be compatible with a
v22.*
version of the backend services they're connected to. This means they can only upgrade exactly when their RPC/Horizon provider upgrades, which is a violation of the previous compatibility guarantees we provide the ecosystem. That guideline essentially boils down to:To maintain this principle, we are releasing new release candidates of Horizon and Stellar RPC to increase the backwards-compatibility of various interfaces and make it easier for people to have a smooth upgrade. We are also asking SDK maintainers to use these new, smoother interfaces to ensure that users can upgrade to the latest version of their SDKs without requiring their use exclusively with Protocol 22-compatible software. In other words, users should be able to upgrade today and not rely on v22 versions of Horizon or RPC deployed for their dependent network.
Stellar RPC:
v22.0.0-rc3
In this release, we are reintroducing fields that previously constituted breaking changes:
getTransactions
would encodecreatedAt
as astring
instead ofnumber
. This change has been reverted. The next release will continue to encode it as anumber
(specifically, auint32
).getVersionInfo
would now use camelCasing over snake_case. This change is now additive. The response schema in the next release will contains both variants:getEvents
replacedpagingToken
withcursor
within each event for pagination. This change is now additive, and the response schema will now include both fields. Please note that theid
field will continue to match both the oldpagingToken
and the newcursor
.simulateTransaction
removed the deprecatedcost
field. This change remains, because it does not require a "lockstep" upgrade with their provider: users can acquire the new costs by extracting them from the transaction resource data. For example,// after: let resources = result.transactionData.build().resources(); let cost: rpc.Api.Cost = { cpuInsns: resources.instructions().toString(), memBytes: (resources.readBytes() + resources.writeBytes()).toString(), };
Horizon:
v22.0.0-rc2
Similarly, we are reintroducing fields that previously constituted breaking changes:
/transaction_async
endpoint changederrorResultXdr
:arrow_right:error_result_xdr
. This change is now additive, and in the next release the response schema will have both fields./asset
endpoint droppednum_accounts
andamount
, and the/transactions/:id
endpoint droppedvalid_before
andvalid_after
. These changes remain, because the values still exist in other locations. Namely,num_accounts
andamount
are inside ofaccounts
, whilevalid_before
andvalid_after
are equivalent to the values in thepreconditions
object.Maintainer Actions
Please ensure that users can upgrade to your latest SDK version without depending exclusively on the breaking schemas in Horizon v22.0.0-rc1 and Stellar RPC v22.0.0-rc2. Users should be able to upgrade today and not rely on v22 versions of Horizon or RPC deployed for their dependent network.
Please release your Protocol-22 compatible software releases as release candidates, because things are still subject to change.
As outlined above, breaking changes are still acceptable if there is an alternative, client-side way of acquiring the same field but not if the field is only present in a v22 version of the backend service. These are part of the natural transition to a new version that clients should be prepared for.
A concrete example: someone with an existing codebase may have code written that uses the
createdAt
field returned byrpc.getTransaction
. If they upgrade to the latest version, their code will break because the field is now strictly typed as astring
. And yet, if they were to update their code accordingly, their code would not function unless they pointed at a v22 RPC. This is the lockstep upgrade we are trying to avoid. This is in contrast to a change likecost
being removed, because they can write code that works on both v21 and v22 RPCs by using the existingtransactionData
field to migrate.Reference Implementations
JavaScript: stellar/js-stellar-sdk#1084