Skip to content
This repository was archived by the owner on Mar 11, 2025. It is now read-only.

Commit 3fff672

Browse files
authored
Handle events without contract IDs correctly (#172)
* Add deprecation message & migration guide * Add getEvents fixes to mirror stellar/stellar-sdk#833 * Update deprecation message with a specific version * Update to match stellar-sdk implementation * Add fixups for Node 20
1 parent abc79fc commit 3fff672

File tree

8 files changed

+195
-55
lines changed

8 files changed

+195
-55
lines changed

.github/workflows/npm_publish.yml

+6-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,9 @@ jobs:
1313
- name: Install Node
1414
uses: actions/setup-node@v3
1515
with:
16-
node-version: 16
16+
node-version: '18.x'
1717
registry-url: 'https://registry.npmjs.org'
18+
always-auth: true
1819

1920
- name: Install Depencencies
2021
run: yarn install
@@ -23,6 +24,9 @@ jobs:
2324
run: yarn preversion
2425

2526
- name: Publish npm package
26-
run: yarn publish
27+
run: |
28+
yarn publish
29+
npm deprecate soroban-client@latest \
30+
"⚠️ This package is now deprecated: transition to `stellar-sdk@beta`, instead! 🚚 All future updates and bug fixes will happen there. Please refer to the migration guide for details on porting your codebase: https://github.com/stellar/js-soroban-client/tree/main/docs/migration.md"
2731
env:
2832
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

.github/workflows/tests.yml

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ jobs:
1313
fail-fast: false
1414
max-parallel: 4
1515
matrix:
16-
node-version: [16, 18, 20]
16+
node-version: [18, 20]
1717

1818
steps:
1919
- name: Checkout

CHANGELOG.md

+7
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,13 @@
55
A breaking change should be clearly marked in this log.
66

77

8+
## Unreleased
9+
10+
### Fixed
11+
* The `Server.getEvents` method now correctly parses responses without a `contractId` field set: the `events[i].contractId` field on an event will be omitted if there was no ID in the event (e.g. for system events; ([#172](https://github.com/stellar/js-soroban-client/pull/172))).
12+
* The `Server.getEvents()` method will correctly parse the event value as an `xdr.ScVal` rather than an `xdr.DiagnosticEvent` ([#172](https://github.com/stellar/js-soroban-client/pull/172)).
13+
14+
815
## v1.0.0-beta.4
916

1017
### Fixed

docs/migration.md

+118
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,118 @@
1+
**This library is deprecated in favor of `stellar-sdk`.**
2+
3+
## Migrating to `stellar-sdk`
4+
5+
This migration guide is focused towards former users of `soroban-client`, but you can refer to the [full migration guide](https://gist.github.com/Shaptic/5ce4f16d9cce7118f391fbde398c2f30/) for more details.
6+
7+
### Why?
8+
9+
Many applications built on Stellar need to utilize both [Horizon](https://developers.stellar.org/docs/fundamentals-and-concepts/stellar-stack#horizon-api) (in order to support Stellar's existing, native functionality and do things like query transaction history, manage DEX offers, etc.) as well as [Soroban RPC](https://soroban.stellar.org/docs/reference/rpc) (in order to interact with smart contracts, retrieve event streams, etc.). By separating support for these two APIs across two SDKs, the applications have unnecessary bloat and code duplication. They both have a unified interface: the protocol XDR (which is abstracted by [`stellar-base`](https://www.npmjs.com/package/stellar-base)), and so it makes sense for a single package to have modules for communicating with either of the interfaces.
10+
11+
If you *just* need Soroban RPC (which is likely the case given that you're in this repository), you can continue to just use those pieces. The only adaptation necessary is updating module references.
12+
13+
### Module Philosophy
14+
15+
All of the abstractions related to Soroban RPC live under the `SorobanRpc` namespace, and the API definitions live under `SorobanRpc.Api`:
16+
17+
```js
18+
// before:
19+
import * as SorobanClient from 'soroban-client';
20+
21+
const s = SorobanClient.Server("...");
22+
const r: SorobanClient.SorobanRpc.GetTransactionResponse = s.getTransaction("...");
23+
24+
// after:
25+
import { SorobanRpc } from 'soroban-client';
26+
27+
const s = SorobanRpc.Server("...");
28+
const r: SorobanRpc.Api.GetTransactionResponse = s.getTransaction("...");
29+
```
30+
31+
All of the _shared_ interfaces, such as those for building operations, dealing with accounts, or touch the XDR in any way (i.e. the fundamental building blocks of the Stellar protocol) still live at the top level. For example,
32+
33+
```js
34+
import {
35+
Account,
36+
TransactionBuilder,
37+
SorobanDataBuilder
38+
} from 'stellar-sdk';
39+
```
40+
41+
(If you've ever imported and used `stellar-base` directly, then this distinction should be clear: anything found in `stellar-base` lives in the top-level module.)
42+
43+
### Migration Details
44+
45+
To migrate, you will need to identify where you are interacting with the RPC server vs. just interacting with the Stellar protocol. Namely,
46+
47+
* `Server` now lives under the `SorobanRpc` submodule
48+
* Soroban helpers such as `assembleTransaction` also live under this submodule
49+
* The API definitions now live in the `SorobanRpc.Api` submodule
50+
* Helpers that are "shared" and have nothing to do with the RPC (like `TransactionBuilder` and `ContractSpec`) are still in the top level
51+
52+
Here's an example before-and-after set of scripts:
53+
54+
Before:
55+
56+
```typescript
57+
import * as SorobanClient from 'soroban-client';
58+
59+
const s = SorobanClient.Server('https://rpc-futurenet.stellar.org');
60+
const kp = SorobanClient.Keypair.random();
61+
const c = new Contract("C...");
62+
63+
async function main() {
64+
return s.getAccount(kp.publicKey()).then(account => {
65+
const tx = new SorobanClient.TransactionBuilder(account, {
66+
fee: BASE_FEE
67+
})
68+
.addOperation(c.call("hello", SorobanClient.scValToNative("world")))
69+
.setNetworkPassphrase(StellarSdk.Networks.FUTURENET)
70+
.setTimeout(30)
71+
.build();
72+
73+
let sim: SorobanClient.SorobanRpc.SimulateTransactionResult;
74+
sim = await s.simulateTransaction(tx);
75+
const readyTx = SorobanClient.assembleTransaction(
76+
tx,
77+
StellarSdk.Networks.FUTURENET,
78+
sim);
79+
80+
readyTx.sign(kp);
81+
return s.submitTransaction(readyTx);
82+
});
83+
}
84+
```
85+
86+
After:
87+
88+
```typescript
89+
import {
90+
Keypair,
91+
Networks,
92+
TransactionBuilder,
93+
Operation,
94+
scValToNative,
95+
SorobanRpc
96+
} from 'stellar-sdk';
97+
const { Api, assembleTransaction } = SorobanRpc;
98+
99+
const s = SorobanRpc.Server('https://horizon-testnet.stellar.org');
100+
const kp = Keypair.random();
101+
102+
async function main() {
103+
return s.getAccount(kp.publicKey()).then(account => {
104+
const tx = new TransactionBuilder(account, { fee: BASE_FEE })
105+
.addOperation(c.call("hello", scValToNative("world")))
106+
.setNetworkPassphrase(Networks.FUTURENET)
107+
.setTimeout(30)
108+
.build();
109+
110+
let sim: Api.SimulateTransactionResult;
111+
sim = await s.simulateTransaction(tx);
112+
const readyTx = assembleTransaction(tx, Networks.FUTURENET, sim);
113+
readyTx.sign(kp);
114+
115+
return s.submitTransaction(readyTx);
116+
});
117+
}
118+
```

src/parsers.ts

+9-3
Original file line numberDiff line numberDiff line change
@@ -23,11 +23,17 @@ export function parseRawEvents(
2323
return {
2424
latestLedger: r.latestLedger,
2525
events: (r.events ?? []).map((evt) => {
26+
const clone: Omit<SorobanRpc.RawEventResponse, 'contractId'> = { ...evt };
27+
delete (clone as any).contractId; // `as any` hack because contractId field isn't optional
28+
29+
// the contractId may be empty so we omit the field in that case
2630
return {
27-
...evt,
28-
contractId: new Contract(evt.contractId),
31+
...clone,
32+
...(evt.contractId !== '' && {
33+
contractId: new Contract(evt.contractId)
34+
}),
2935
topic: evt.topic.map((topic) => xdr.ScVal.fromXDR(topic, 'base64')),
30-
value: xdr.DiagnosticEvent.fromXDR(evt.value.xdr, 'base64')
36+
value: xdr.ScVal.fromXDR(evt.value.xdr, 'base64')
3137
};
3238
})
3339
};

src/soroban_rpc.ts

+3-3
Original file line numberDiff line numberDiff line change
@@ -146,9 +146,9 @@ export namespace SorobanRpc {
146146
}
147147

148148
interface EventResponse extends BaseEventResponse {
149-
contractId: Contract;
149+
contractId?: Contract;
150150
topic: xdr.ScVal[];
151-
value: xdr.DiagnosticEvent;
151+
value: xdr.ScVal;
152152
}
153153

154154
export interface RawGetEventsResponse {
@@ -165,7 +165,7 @@ export namespace SorobanRpc {
165165
inSuccessfulContractCall: boolean;
166166
}
167167

168-
interface RawEventResponse extends BaseEventResponse {
168+
export interface RawEventResponse extends BaseEventResponse {
169169
contractId: string;
170170
topic: string[];
171171
value: {

0 commit comments

Comments
 (0)