Skip to content

Commit

Permalink
Add support for stable Protocol 20 release (both XDR and RPC schemas) (
Browse files Browse the repository at this point in the history
…#886)

* Add all changes matching stellar/js-soroban-client#167
* Refresh yarn.lock
* Fixup Node versions, etc.
* Rename stable package under the `@stellar/` organization (#887)
  • Loading branch information
Shaptic committed Dec 6, 2023
1 parent c17718d commit f3228f6
Show file tree
Hide file tree
Showing 18 changed files with 915 additions and 1,144 deletions.
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",
"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

0 comments on commit f3228f6

Please sign in to comment.