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

Add support for stable Protocol 20 release (both XDR and RPC schemas) #886

Merged
merged 6 commits into from
Dec 6, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
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
4 changes: 2 additions & 2 deletions .github/workflows/bundle_size.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,10 @@ jobs:
steps:
- uses: actions/checkout@v3

- name: Install Node.js 16
- name: Install Node.js 18
uses: actions/setup-node@v3
with:
node-version: 16
node-version: 18

# Workaround for some `yarn` nonsense, see:
# https://github.com/yarnpkg/yarn/issues/6312#issuecomment-429685210
Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/gh_pages.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,10 @@ jobs:
repository: stellar/js-stellar-base
path: js-stellar-base

- name: Install Node (16.x)
- name: Install Node (20.x)
uses: actions/setup-node@v3
with:
node-version: 16
node-version: '20.x'

- name: Install Dependencies
run: yarn install
Expand Down
16 changes: 13 additions & 3 deletions .github/workflows/npm_publish.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,16 +13,26 @@ jobs:
- name: Install Node
uses: actions/setup-node@v3
with:
node-version: 16
node-version: '18.x'
registry-url: 'https://registry.npmjs.org'
always-auth: true

- name: Install Depencencies
run: yarn install

- name: Build, Test, and Package
run: yarn preversion

- name: Publish npm package
run: yarn publish --tag beta
- name: Publish npm package to both places
run: |
yarn publish --access public
sed -i -e 's#"@stellar/stellar-sdk"#"stellar-sdk"#' package.json
yarn publish
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}

- name: Deprecate the old package
run: |
npm deprecate stellar-sdk@latest "⚠️ This package has moved to @stellar/stellar-sdk! 🚚"
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
2 changes: 1 addition & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ jobs:
fail-fast: false
max-parallel: 4
matrix:
node-version: [16, 18]
node-version: [18, 20]

steps:
- name: Checkout
Expand Down
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
{
"name": "stellar-sdk",
"name": "@stellar/stellar-sdk",
"version": "11.0.0-beta.6",
"description": "A library for working with the Stellar network, including communication with the Horizon and Soroban RPC servers.",
"keywords": [
Expand Down Expand Up @@ -146,7 +146,7 @@
"bignumber.js": "^9.1.2",
"eventsource": "^2.0.2",
"randombytes": "^2.1.0",
"stellar-base": "10.0.0-beta.4",
"stellar-base": "git+https://github.com/stellar/js-stellar-base#master",
Copy link

@sreuland sreuland Dec 6, 2023

Choose a reason for hiding this comment

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

will this pr wait on stellar-base to release first, and pin this to 10.0.0 here, or you anticipate doing another release prep pr with that bump?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I think we can merge because this won't be released, and then have a separate PR to update to the stable git ref and bump to the stable version. This will make it easier to isolate the changes that need to be reviewed! And we can use master as the gitref for E2E tests. Wdyt?

Copy link

Choose a reason for hiding this comment

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

yes, that works, could also git ref to the pr for e2e concerns, so whichever process is preferred, I just was curious on the pinning aspect there, thanks!

"toml": "^3.0.0",
"urijs": "^1.19.1"
}
Expand Down
35 changes: 15 additions & 20 deletions src/soroban/api.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
import { AssetType, Contract, SorobanDataBuilder, xdr } from 'stellar-base';

// TODO: Better parsing for hashes

/* tslint:disable-next-line:no-namespace */
/** @namespace Api */
export namespace Api {
Expand All @@ -26,7 +24,7 @@ export namespace Api {
lastModifiedLedgerSeq?: number;
key: xdr.LedgerKey;
val: xdr.LedgerEntryData;
expirationLedgerSeq?: number;
liveUntilLedgerSeq?: number;
}

export interface RawLedgerEntryResult {
Expand All @@ -38,7 +36,7 @@ export namespace Api {
/** optional, a future ledger number upon which this entry will expire
* based on https://github.com/stellar/soroban-tools/issues/1010
*/
expirationLedgerSeq?: number;
liveUntilLedgerSeq?: number;
}

/** An XDR-parsed version of {@link RawLedgerEntryResult} */
Expand All @@ -53,16 +51,14 @@ export namespace Api {
latestLedger: number;
}

/* Response for jsonrpc method `getNetwork`
*/
/** @see https://soroban.stellar.org/api/methods/getNetwork */
export interface GetNetworkResponse {
friendbotUrl?: string;
passphrase: string;
protocolVersion: string;
}

/* Response for jsonrpc method `getLatestLedger`
*/
/** @see https://soroban.stellar.org/api/methods/getLatestLedger */
export interface GetLatestLedgerResponse {
id: string;
sequence: number;
Expand All @@ -75,16 +71,17 @@ export namespace Api {
FAILED = 'FAILED'
}

/** @see https://soroban.stellar.org/api/methods/getTransaction */
export type GetTransactionResponse =
| GetSuccessfulTransactionResponse
| GetFailedTransactionResponse
| GetMissingTransactionResponse;

interface GetAnyTransactionResponse {
status: GetTransactionStatus;
latestLedger: string;
latestLedger: number;
latestLedgerCloseTime: number;
oldestLedger: string;
oldestLedger: number;
oldestLedgerCloseTime: number;
}

Expand Down Expand Up @@ -123,9 +120,9 @@ export namespace Api {

export interface RawGetTransactionResponse {
status: GetTransactionStatus;
latestLedger: string;
latestLedger: number;
latestLedgerCloseTime: number;
oldestLedger: string;
oldestLedger: number;
oldestLedgerCloseTime: number;

// the fields below are set if status is SUCCESS
Expand All @@ -147,7 +144,7 @@ export namespace Api {
}

export interface GetEventsResponse {
latestLedger: string;
latestLedger: number;
events: EventResponse[];
}

Expand All @@ -158,14 +155,14 @@ export namespace Api {
}

export interface RawGetEventsResponse {
latestLedger: string;
latestLedger: number;
events: RawEventResponse[];
}

interface BaseEventResponse {
id: string;
type: EventType;
ledger: string;
ledger: number;
ledgerClosedAt: string;
pagingToken: string;
inSuccessfulContractCall: boolean;
Expand All @@ -174,9 +171,7 @@ export namespace Api {
export interface RawEventResponse extends BaseEventResponse {
contractId: string;
topic: string[];
value: {
xdr: string;
};
value: string;
}

export interface RequestAirdropResponse {
Expand Down Expand Up @@ -238,7 +233,7 @@ export namespace Api {
id: string;

/** always present: the LCL known to the server when responding */
latestLedger: string;
latestLedger: number;

/**
* The field is always present, but may be empty in cases where:
Expand Down Expand Up @@ -328,7 +323,7 @@ export namespace Api {
/** @see https://soroban.stellar.org/api/methods/simulateTransaction#returns */
export interface RawSimulateTransactionResponse {
id: string;
latestLedger: string;
latestLedger: number;
error?: string;
// this is an xdr.SorobanTransactionData in base64
transactionData?: string;
Expand Down
6 changes: 4 additions & 2 deletions src/soroban/parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export function parseRawEvents(
...clone,
...(evt.contractId !== '' && { contractId: new Contract(evt.contractId) }),
topic: evt.topic.map((topic) => xdr.ScVal.fromXDR(topic, 'base64')),
value: xdr.ScVal.fromXDR(evt.value.xdr, 'base64')
value: xdr.ScVal.fromXDR(evt.value, 'base64')
};
})
};
Expand All @@ -53,7 +53,9 @@ export function parseRawLedgerEntries(
lastModifiedLedgerSeq: rawEntry.lastModifiedLedgerSeq,
key: xdr.LedgerKey.fromXDR(rawEntry.key, 'base64'),
val: xdr.LedgerEntryData.fromXDR(rawEntry.xdr, 'base64'),
expirationLedgerSeq: rawEntry.expirationLedgerSeq
...(rawEntry.liveUntilLedgerSeq !== undefined && {
liveUntilLedgerSeq: rawEntry.liveUntilLedgerSeq
})
};
})
};
Expand Down
99 changes: 11 additions & 88 deletions src/soroban/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,7 @@ import {
FeeBumpTransaction,
Keypair,
Transaction,
xdr,
hash
xdr
} from 'stellar-base';

import AxiosClient from './axios';
Expand Down Expand Up @@ -169,7 +168,7 @@ export class Server {
* const key = xdr.ScVal.scvSymbol("counter");
* server.getContractData(contractId, key, Durability.Temporary).then(data => {
* console.log("value:", data.val);
* console.log("expirationLedgerSeq:", data.expirationLedgerSeq);
* console.log("liveUntilLedgerSeq:", data.liveUntilLedgerSeq);
* console.log("lastModified:", data.lastModifiedLedgerSeq);
* console.log("latestLedger:", data.latestLedger);
* });
Expand Down Expand Up @@ -259,7 +258,7 @@ export class Server {
* const ledgerData = response.entries[0];
* console.log("key:", ledgerData.key);
* console.log("value:", ledgerData.val);
* console.log("expirationLedgerSeq:", ledgerData.expirationLedgerSeq);
* console.log("liveUntilLedgerSeq:", ledgerData.liveUntilLedgerSeq);
* console.log("lastModified:", ledgerData.lastModifiedLedgerSeq);
* console.log("latestLedger:", response.latestLedger);
* });
Expand All @@ -275,11 +274,8 @@ export class Server {
.post<Api.RawGetLedgerEntriesResponse>(
this.serverURL.toString(),
'getLedgerEntries',
expandRequestIncludeExpirationLedgers(keys).map((k) =>
k.toXDR('base64')
)
)
.then((response) => mergeResponseExpirationLedgers(response, keys));
keys.map((k) => k.toXDR('base64'))
);
}

/**
Expand Down Expand Up @@ -454,13 +450,13 @@ export class Server {
*
* @param {Transaction | FeeBumpTransaction} transaction the transaction to
* simulate, which should include exactly one operation (one of
* {@link xdr.InvokeHostFunctionOp}, {@link xdr.BumpFootprintExpirationOp},
* or {@link xdr.RestoreFootprintOp}). Any provided footprint or auth
* {@link xdr.InvokeHostFunctionOp}, {@link xdr.ExtendFootprintTTLOp}, or
* {@link xdr.RestoreFootprintOp}). Any provided footprint or auth
* information will be ignored.
*
* @returns {Promise<Api.SimulateTransactionResponse>} an object with
* the cost, footprint, result/auth requirements (if applicable), and error
* of the transaction
* @returns {Promise<Api.SimulateTransactionResponse>} an object with the
* cost, footprint, result/auth requirements (if applicable), and error of
* the transaction
*
* @see https://developers.stellar.org/docs/glossary/transactions/
* @see https://soroban.stellar.org/api/methods/simulateTransaction
Expand Down Expand Up @@ -525,7 +521,7 @@ export class Server {
*
* @param {Transaction | FeeBumpTransaction} transaction the transaction to
* prepare. It should include exactly one operation, which must be one of
* {@link xdr.InvokeHostFunctionOp}, {@link xdr.BumpFootprintExpirationOp},
* {@link xdr.InvokeHostFunctionOp}, {@link xdr.ExtendFootprintTTLOp},
* or {@link xdr.RestoreFootprintOp}.
*
* Any provided footprint will be overwritten. However, if your operation
Expand Down Expand Up @@ -738,76 +734,3 @@ function findCreatedAccountSequenceInTransactionMeta(

throw new Error('No account created in transaction');
}

// TODO - remove once rpc updated to
// append expiration entry per data LK requested onto server-side response
// https://github.com/stellar/soroban-tools/issues/1010
function mergeResponseExpirationLedgers(
ledgerEntriesResponse: Api.RawGetLedgerEntriesResponse,
requestedKeys: xdr.LedgerKey[]
): Api.RawGetLedgerEntriesResponse {
const requestedKeyXdrs = new Set<String>(
requestedKeys.map((requestedKey) => requestedKey.toXDR('base64'))
);
const expirationKeyToRawEntryResult = new Map<
String,
Api.RawLedgerEntryResult
>();
(ledgerEntriesResponse.entries ?? []).forEach((rawEntryResult) => {
if (!rawEntryResult.key || !rawEntryResult.xdr) {
throw new TypeError(
`invalid ledger entry: ${JSON.stringify(rawEntryResult)}`
);
}
const parsedKey = xdr.LedgerKey.fromXDR(rawEntryResult.key, 'base64');
const isExpirationMeta =
parsedKey.switch().value === xdr.LedgerEntryType.expiration().value &&
!requestedKeyXdrs.has(rawEntryResult.key);
const keyHash = isExpirationMeta
? parsedKey.expiration().keyHash().toString()
: hash(parsedKey.toXDR()).toString();

const rawEntry =
expirationKeyToRawEntryResult.get(keyHash) ?? rawEntryResult;

if (isExpirationMeta) {
const expirationLedgerSeq = xdr.LedgerEntryData.fromXDR(
rawEntryResult.xdr,
'base64'
)
.expiration()
.expirationLedgerSeq();
expirationKeyToRawEntryResult.set(keyHash, {
...rawEntry,
expirationLedgerSeq
});
} else {
expirationKeyToRawEntryResult.set(keyHash, {
...rawEntry,
...rawEntryResult
});
}
});

ledgerEntriesResponse.entries = [...expirationKeyToRawEntryResult.values()];
return ledgerEntriesResponse;
}

// TODO - remove once rpc updated to
// include expiration entry on responses for any data LK's requested
// https://github.com/stellar/soroban-tools/issues/1010
function expandRequestIncludeExpirationLedgers(
keys: xdr.LedgerKey[]
): xdr.LedgerKey[] {
return keys.concat(
keys
.filter(
(key) => key.switch().value !== xdr.LedgerEntryType.expiration().value
)
.map((key) =>
xdr.LedgerKey.expiration(
new xdr.LedgerKeyExpiration({ keyHash: hash(key.toXDR()) })
)
)
);
}
4 changes: 2 additions & 2 deletions src/soroban/transaction.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ export function assembleTransaction(
if (!isSorobanTransaction(raw)) {
throw new TypeError(
'unsupported transaction: must contain exactly one ' +
'invokeHostFunction, bumpFootprintExpiration, or restoreFootprint ' +
'invokeHostFunction, extendFootprintTtl, or restoreFootprint ' +
'operation'
);
}
Expand Down Expand Up @@ -101,7 +101,7 @@ function isSorobanTransaction(tx: Transaction): boolean {

switch (tx.operations[0].type) {
case 'invokeHostFunction':
case 'bumpFootprintExpiration':
case 'extendFootprintTtl':
case 'restoreFootprint':
return true;

Expand Down
Loading
Loading