diff --git a/package.json b/package.json index 53a5ca45..f8ee4e78 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "stellar-base", - "version": "8.2.2-soroban.11", + "version": "8.2.2-soroban.12", "description": "Low level stellar support library", "main": "./lib/index.js", "types": "./types/index.d.ts", diff --git a/src/address.js b/src/address.js index beed4f41..46089a97 100644 --- a/src/address.js +++ b/src/address.js @@ -57,6 +57,33 @@ export class Address { return new Address(StrKey.encodeContract(buffer)); } + /** + * Convert this from an xdr.ScVal type + * + * @param {xdr.ScVal} scVal - The xdr.ScVal type to parse + * @returns {Address} + */ + static fromScVal(scVal) { + return Address.fromScAddress(scVal.address()); + } + + /** + * Convert this from an xdr.ScAddress type + * + * @param {xdr.ScAddress} scAddress - The xdr.ScAddress type to parse + * @returns {Address} + */ + static fromScAddress(scAddress) { + switch (scAddress.switch()) { + case xdr.ScAddressType.scAddressTypeAccount(): + return Address.account(scAddress.accountId().ed25519()); + case xdr.ScAddressType.scAddressTypeContract(): + return Address.contract(scAddress.contractId()); + default: + throw new Error('Unsupported address type'); + } + } + /** * Serialize an address to string. * @@ -79,7 +106,7 @@ export class Address { * @returns {xdr.ScVal} */ toScVal() { - return xdr.ScVal.scvObject(xdr.ScObject.scoAddress(this.toScAddress())); + return xdr.ScVal.scvAddress(this.toScAddress()); } /** diff --git a/src/contract.js b/src/contract.js index d897723f..85b6f5b2 100644 --- a/src/contract.js +++ b/src/contract.js @@ -39,7 +39,7 @@ export class Contract { const contractId = Buffer.from(this._id, 'hex'); return Operation.invokeHostFunction({ function: xdr.HostFunction.hostFunctionTypeInvokeContract([ - xdr.ScVal.scvObject(xdr.ScObject.scoBytes(contractId)), + xdr.ScVal.scvBytes(contractId), xdr.ScVal.scvSymbol(method), ...params ]), @@ -49,7 +49,7 @@ export class Contract { xdr.LedgerKey.contractData( new xdr.LedgerKeyContractData({ contractId, - key: xdr.ScVal.scvStatic(xdr.ScStatic.scsLedgerKeyContractCode()) + key: xdr.ScVal.scvLedgerKeyContractExecutable() }) ) ], diff --git a/src/generated/next_generated.js b/src/generated/next_generated.js index 9d4c5b91..94d6dc37 100644 --- a/src/generated/next_generated.js +++ b/src/generated/next_generated.js @@ -280,20 +280,6 @@ xdr.typedef("String64", xdr.string(64)); // =========================================================================== xdr.typedef("SequenceNumber", xdr.lookup("Int64")); -// === xdr source ============================================================ -// -// typedef uint64 TimePoint; -// -// =========================================================================== -xdr.typedef("TimePoint", xdr.lookup("Uint64")); - -// === xdr source ============================================================ -// -// typedef uint64 Duration; -// -// =========================================================================== -xdr.typedef("Duration", xdr.lookup("Uint64")); - // === xdr source ============================================================ // // typedef opaque DataValue<64>; @@ -4614,13 +4600,13 @@ xdr.union("ContractId", { // struct CreateContractArgs // { // ContractID contractID; -// SCContractCode source; +// SCContractExecutable source; // }; // // =========================================================================== xdr.struct("CreateContractArgs", [ ["contractId", xdr.lookup("ContractId")], - ["source", xdr.lookup("ScContractCode")], + ["source", xdr.lookup("ScContractExecutable")], ]); // === xdr source ============================================================ @@ -5007,14 +4993,14 @@ xdr.struct("HashIdPreimageSourceAccountContractId", [ // struct // { // Hash networkID; -// SCContractCode source; +// SCContractExecutable source; // uint256 salt; // } // // =========================================================================== xdr.struct("HashIdPreimageCreateContractArgs", [ ["networkId", xdr.lookup("Hash")], - ["source", xdr.lookup("ScContractCode")], + ["source", xdr.lookup("ScContractExecutable")], ["salt", xdr.lookup("Uint256")], ]); @@ -5085,7 +5071,7 @@ xdr.struct("HashIdPreimageContractAuth", [ // struct // { // Hash networkID; -// SCContractCode source; +// SCContractExecutable source; // uint256 salt; // } createContractArgs; // case ENVELOPE_TYPE_CONTRACT_AUTH: @@ -7896,6 +7882,20 @@ xdr.typedef("Uint64", xdr.uhyper()); // =========================================================================== xdr.typedef("Int64", xdr.hyper()); +// === xdr source ============================================================ +// +// typedef uint64 TimePoint; +// +// =========================================================================== +xdr.typedef("TimePoint", xdr.lookup("Uint64")); + +// === xdr source ============================================================ +// +// typedef uint64 Duration; +// +// =========================================================================== +xdr.typedef("Duration", xdr.lookup("Uint64")); + // === xdr source ============================================================ // // union ExtensionPoint switch (int v) @@ -8119,55 +8119,88 @@ xdr.struct("HmacSha256Mac", [ ["mac", xdr.opaque(32)], ]); -// === xdr source ============================================================ -// -// typedef string SCSymbol<10>; -// -// =========================================================================== -xdr.typedef("ScSymbol", xdr.string(10)); - // === xdr source ============================================================ // // enum SCValType // { -// SCV_U63 = 0, -// SCV_U32 = 1, -// SCV_I32 = 2, -// SCV_STATIC = 3, -// SCV_OBJECT = 4, -// SCV_SYMBOL = 5, -// SCV_BITSET = 6, -// SCV_STATUS = 7 +// SCV_BOOL = 0, +// SCV_VOID = 1, +// SCV_STATUS = 2, +// +// // 32 bits is the smallest type in WASM or XDR; no need for u8/u16. +// SCV_U32 = 3, +// SCV_I32 = 4, +// +// // 64 bits is naturally supported by both WASM and XDR also. +// SCV_U64 = 5, +// SCV_I64 = 6, +// +// // Time-related u64 subtypes with their own functions and formatting. +// SCV_TIMEPOINT = 7, +// SCV_DURATION = 8, +// +// // 128 bits is naturally supported by Rust and we use it for Soroban +// // fixed-point arithmetic prices / balances / similar "quantities". These +// // are represented in XDR as a pair of 2 u64s, unlike {u,i}256 which is +// // represented as an array of 32 bytes. +// SCV_U128 = 9, +// SCV_I128 = 10, +// +// // 256 bits is the size of sha256 output, ed25519 keys, and the EVM machine +// // word, so for interop use we include this even though it requires a small +// // amount of Rust guest and/or host library code. +// SCV_U256 = 11, +// SCV_I256 = 12, +// +// // TODO: possibly allocate subtypes of i64, i128 and/or u256 for +// // fixed-precision with a specific number of decimals. +// +// // Bytes come in 3 flavors, 2 of which have meaningfully different +// // formatting and validity-checking / domain-restriction. +// SCV_BYTES = 13, +// SCV_STRING = 14, +// SCV_SYMBOL = 15, +// +// // Vecs and maps are just polymorphic containers of other ScVals. +// SCV_VEC = 16, +// SCV_MAP = 17, +// +// // SCContractExecutable and SCAddressType are types that gets used separately from +// // SCVal so we do not flatten their structures into separate SCVal cases. +// SCV_CONTRACT_EXECUTABLE = 18, +// SCV_ADDRESS = 19, +// +// // SCV_LEDGER_KEY_CONTRACT_EXECUTABLE and SCV_LEDGER_KEY_NONCE are unique +// // symbolic SCVals used as the key for ledger entries for a contract's code +// // and an address' nonce, respectively. +// SCV_LEDGER_KEY_CONTRACT_EXECUTABLE = 20, +// SCV_LEDGER_KEY_NONCE = 21 // }; // // =========================================================================== xdr.enum("ScValType", { - scvU63: 0, - scvU32: 1, - scvI32: 2, - scvStatic: 3, - scvObject: 4, - scvSymbol: 5, - scvBitset: 6, - scvStatus: 7, -}); - -// === xdr source ============================================================ -// -// enum SCStatic -// { -// SCS_VOID = 0, -// SCS_TRUE = 1, -// SCS_FALSE = 2, -// SCS_LEDGER_KEY_CONTRACT_CODE = 3 -// }; -// -// =========================================================================== -xdr.enum("ScStatic", { - scsVoid: 0, - scsTrue: 1, - scsFalse: 2, - scsLedgerKeyContractCode: 3, + scvBool: 0, + scvVoid: 1, + scvStatus: 2, + scvU32: 3, + scvI32: 4, + scvU64: 5, + scvI64: 6, + scvTimepoint: 7, + scvDuration: 8, + scvU128: 9, + scvI128: 10, + scvU256: 11, + scvI256: 12, + scvBytes: 13, + scvString: 14, + scvSymbol: 15, + scvVec: 16, + scvMap: 17, + scvContractExecutable: 18, + scvAddress: 19, + scvLedgerKeyContractExecutable: 20, + scvLedgerKeyNonce: 21, }); // === xdr source ============================================================ @@ -8451,100 +8484,94 @@ xdr.union("ScStatus", { // === xdr source ============================================================ // -// union SCVal switch (SCValType type) +// struct Int128Parts { +// // Both signed and unsigned 128-bit ints +// // are transported in a pair of uint64s +// // to reduce the risk of sign-extension. +// uint64 lo; +// uint64 hi; +// }; +// +// =========================================================================== +xdr.struct("Int128Parts", [ + ["lo", xdr.lookup("Uint64")], + ["hi", xdr.lookup("Uint64")], +]); + +// === xdr source ============================================================ +// +// enum SCContractExecutableType // { -// case SCV_U63: -// int64 u63; -// case SCV_U32: -// uint32 u32; -// case SCV_I32: -// int32 i32; -// case SCV_STATIC: -// SCStatic ic; -// case SCV_OBJECT: -// SCObject* obj; -// case SCV_SYMBOL: -// SCSymbol sym; -// case SCV_BITSET: -// uint64 bits; -// case SCV_STATUS: -// SCStatus status; +// SCCONTRACT_EXECUTABLE_WASM_REF = 0, +// SCCONTRACT_EXECUTABLE_TOKEN = 1 // }; // // =========================================================================== -xdr.union("ScVal", { - switchOn: xdr.lookup("ScValType"), +xdr.enum("ScContractExecutableType", { + sccontractExecutableWasmRef: 0, + sccontractExecutableToken: 1, +}); + +// === xdr source ============================================================ +// +// union SCContractExecutable switch (SCContractExecutableType type) +// { +// case SCCONTRACT_EXECUTABLE_WASM_REF: +// Hash wasm_id; +// case SCCONTRACT_EXECUTABLE_TOKEN: +// void; +// }; +// +// =========================================================================== +xdr.union("ScContractExecutable", { + switchOn: xdr.lookup("ScContractExecutableType"), switchName: "type", switches: [ - ["scvU63", "u63"], - ["scvU32", "u32"], - ["scvI32", "i32"], - ["scvStatic", "ic"], - ["scvObject", "obj"], - ["scvSymbol", "sym"], - ["scvBitset", "bits"], - ["scvStatus", "status"], + ["sccontractExecutableWasmRef", "wasmId"], + ["sccontractExecutableToken", xdr.void()], ], arms: { - u63: xdr.lookup("Int64"), - u32: xdr.lookup("Uint32"), - i32: xdr.lookup("Int32"), - ic: xdr.lookup("ScStatic"), - obj: xdr.option(xdr.lookup("ScObject")), - sym: xdr.lookup("ScSymbol"), - bits: xdr.lookup("Uint64"), - status: xdr.lookup("ScStatus"), + wasmId: xdr.lookup("Hash"), }, }); // === xdr source ============================================================ // -// enum SCObjectType +// enum SCAddressType // { -// // We have a few objects that represent non-stellar-specific concepts -// // like general-purpose maps, vectors, numbers, blobs. -// -// SCO_VEC = 0, -// SCO_MAP = 1, -// SCO_U64 = 2, -// SCO_I64 = 3, -// SCO_U128 = 4, -// SCO_I128 = 5, -// SCO_BYTES = 6, -// SCO_CONTRACT_CODE = 7, -// SCO_ADDRESS = 8, -// SCO_NONCE_KEY = 9 -// -// // TODO: add more +// SC_ADDRESS_TYPE_ACCOUNT = 0, +// SC_ADDRESS_TYPE_CONTRACT = 1 // }; // // =========================================================================== -xdr.enum("ScObjectType", { - scoVec: 0, - scoMap: 1, - scoU64: 2, - scoI64: 3, - scoU128: 4, - scoI128: 5, - scoBytes: 6, - scoContractCode: 7, - scoAddress: 8, - scoNonceKey: 9, +xdr.enum("ScAddressType", { + scAddressTypeAccount: 0, + scAddressTypeContract: 1, }); // === xdr source ============================================================ // -// struct SCMapEntry +// union SCAddress switch (SCAddressType type) // { -// SCVal key; -// SCVal val; +// case SC_ADDRESS_TYPE_ACCOUNT: +// AccountID accountId; +// case SC_ADDRESS_TYPE_CONTRACT: +// Hash contractId; // }; // // =========================================================================== -xdr.struct("ScMapEntry", [ - ["key", xdr.lookup("ScVal")], - ["val", xdr.lookup("ScVal")], -]); +xdr.union("ScAddress", { + switchOn: xdr.lookup("ScAddressType"), + switchName: "type", + switches: [ + ["scAddressTypeAccount", "accountId"], + ["scAddressTypeContract", "contractId"], + ], + arms: { + accountId: xdr.lookup("AccountId"), + contractId: xdr.lookup("Hash"), + }, +}); // === xdr source ============================================================ // @@ -8555,165 +8582,186 @@ xdr.const("SCVAL_LIMIT", 256000); // === xdr source ============================================================ // -// typedef SCVal SCVec; +const SCSYMBOL_LIMIT = 32; // // =========================================================================== -xdr.typedef("ScVec", xdr.varArray(xdr.lookup("ScVal"), xdr.lookup("SCVAL_LIMIT"))); +xdr.const("SCSYMBOL_LIMIT", 32); // === xdr source ============================================================ // -// typedef SCMapEntry SCMap; +// typedef SCVal SCVec; // // =========================================================================== -xdr.typedef("ScMap", xdr.varArray(xdr.lookup("ScMapEntry"), xdr.lookup("SCVAL_LIMIT"))); +xdr.typedef("ScVec", xdr.varArray(xdr.lookup("ScVal"), xdr.lookup("SCVAL_LIMIT"))); // === xdr source ============================================================ // -// enum SCContractCodeType -// { -// SCCONTRACT_CODE_WASM_REF = 0, -// SCCONTRACT_CODE_TOKEN = 1 -// }; +// typedef SCMapEntry SCMap; // // =========================================================================== -xdr.enum("ScContractCodeType", { - sccontractCodeWasmRef: 0, - sccontractCodeToken: 1, -}); +xdr.typedef("ScMap", xdr.varArray(xdr.lookup("ScMapEntry"), xdr.lookup("SCVAL_LIMIT"))); // === xdr source ============================================================ // -// union SCContractCode switch (SCContractCodeType type) -// { -// case SCCONTRACT_CODE_WASM_REF: -// Hash wasm_id; -// case SCCONTRACT_CODE_TOKEN: -// void; -// }; +// typedef opaque SCBytes; // // =========================================================================== -xdr.union("ScContractCode", { - switchOn: xdr.lookup("ScContractCodeType"), - switchName: "type", - switches: [ - ["sccontractCodeWasmRef", "wasmId"], - ["sccontractCodeToken", xdr.void()], - ], - arms: { - wasmId: xdr.lookup("Hash"), - }, -}); +xdr.typedef("ScBytes", xdr.varOpaque(SCVAL_LIMIT)); // === xdr source ============================================================ // -// struct Int128Parts { -// // Both signed and unsigned 128-bit ints -// // are transported in a pair of uint64s -// // to reduce the risk of sign-extension. -// uint64 lo; -// uint64 hi; -// }; +// typedef string SCString; // // =========================================================================== -xdr.struct("Int128Parts", [ - ["lo", xdr.lookup("Uint64")], - ["hi", xdr.lookup("Uint64")], -]); +xdr.typedef("ScString", xdr.string(SCVAL_LIMIT)); // === xdr source ============================================================ // -// enum SCAddressType -// { -// SC_ADDRESS_TYPE_ACCOUNT = 0, -// SC_ADDRESS_TYPE_CONTRACT = 1 -// }; +// typedef string SCSymbol; // // =========================================================================== -xdr.enum("ScAddressType", { - scAddressTypeAccount: 0, - scAddressTypeContract: 1, -}); +xdr.typedef("ScSymbol", xdr.string(SCSYMBOL_LIMIT)); // === xdr source ============================================================ // -// union SCAddress switch (SCAddressType type) -// { -// case SC_ADDRESS_TYPE_ACCOUNT: -// AccountID accountId; -// case SC_ADDRESS_TYPE_CONTRACT: -// Hash contractId; +// struct SCNonceKey { +// SCAddress nonce_address; // }; // // =========================================================================== -xdr.union("ScAddress", { - switchOn: xdr.lookup("ScAddressType"), - switchName: "type", - switches: [ - ["scAddressTypeAccount", "accountId"], - ["scAddressTypeContract", "contractId"], - ], - arms: { - accountId: xdr.lookup("AccountId"), - contractId: xdr.lookup("Hash"), - }, -}); +xdr.struct("ScNonceKey", [ + ["nonceAddress", xdr.lookup("ScAddress")], +]); // === xdr source ============================================================ // -// union SCObject switch (SCObjectType type) +// union SCVal switch (SCValType type) // { -// case SCO_VEC: -// SCVec vec; -// case SCO_MAP: -// SCMap map; -// case SCO_U64: +// +// case SCV_BOOL: +// bool b; +// case SCV_VOID: +// void; +// case SCV_STATUS: +// SCStatus error; +// +// case SCV_U32: +// uint32 u32; +// case SCV_I32: +// int32 i32; +// +// case SCV_U64: // uint64 u64; -// case SCO_I64: +// case SCV_I64: // int64 i64; -// case SCO_U128: +// case SCV_TIMEPOINT: +// TimePoint timepoint; +// case SCV_DURATION: +// Duration duration; +// +// case SCV_U128: // Int128Parts u128; -// case SCO_I128: +// case SCV_I128: // Int128Parts i128; -// case SCO_BYTES: -// opaque bin; -// case SCO_CONTRACT_CODE: -// SCContractCode contractCode; -// case SCO_ADDRESS: +// +// case SCV_U256: +// uint256 u256; +// case SCV_I256: +// uint256 i256; +// +// case SCV_BYTES: +// SCBytes bytes; +// case SCV_STRING: +// SCString str; +// case SCV_SYMBOL: +// SCSymbol sym; +// +// // Vec and Map are recursive so need to live +// // behind an option, due to xdrpp limitations. +// case SCV_VEC: +// SCVec *vec; +// case SCV_MAP: +// SCMap *map; +// +// case SCV_CONTRACT_EXECUTABLE: +// SCContractExecutable exec; +// case SCV_ADDRESS: // SCAddress address; -// case SCO_NONCE_KEY: -// SCAddress nonceAddress; +// +// // Special SCVals reserved for system-constructed contract-data +// // ledger keys, not generally usable elsewhere. +// case SCV_LEDGER_KEY_CONTRACT_EXECUTABLE: +// void; +// case SCV_LEDGER_KEY_NONCE: +// SCNonceKey nonce_key; // }; // // =========================================================================== -xdr.union("ScObject", { - switchOn: xdr.lookup("ScObjectType"), +xdr.union("ScVal", { + switchOn: xdr.lookup("ScValType"), switchName: "type", switches: [ - ["scoVec", "vec"], - ["scoMap", "map"], - ["scoU64", "u64"], - ["scoI64", "i64"], - ["scoU128", "u128"], - ["scoI128", "i128"], - ["scoBytes", "bin"], - ["scoContractCode", "contractCode"], - ["scoAddress", "address"], - ["scoNonceKey", "nonceAddress"], + ["scvBool", "b"], + ["scvVoid", xdr.void()], + ["scvStatus", "error"], + ["scvU32", "u32"], + ["scvI32", "i32"], + ["scvU64", "u64"], + ["scvI64", "i64"], + ["scvTimepoint", "timepoint"], + ["scvDuration", "duration"], + ["scvU128", "u128"], + ["scvI128", "i128"], + ["scvU256", "u256"], + ["scvI256", "i256"], + ["scvBytes", "bytes"], + ["scvString", "str"], + ["scvSymbol", "sym"], + ["scvVec", "vec"], + ["scvMap", "map"], + ["scvContractExecutable", "exec"], + ["scvAddress", "address"], + ["scvLedgerKeyContractExecutable", xdr.void()], + ["scvLedgerKeyNonce", "nonceKey"], ], arms: { - vec: xdr.lookup("ScVec"), - map: xdr.lookup("ScMap"), + b: xdr.bool(), + error: xdr.lookup("ScStatus"), + u32: xdr.lookup("Uint32"), + i32: xdr.lookup("Int32"), u64: xdr.lookup("Uint64"), i64: xdr.lookup("Int64"), + timepoint: xdr.lookup("TimePoint"), + duration: xdr.lookup("Duration"), u128: xdr.lookup("Int128Parts"), i128: xdr.lookup("Int128Parts"), - bin: xdr.varOpaque(SCVAL_LIMIT), - contractCode: xdr.lookup("ScContractCode"), + u256: xdr.lookup("Uint256"), + i256: xdr.lookup("Uint256"), + bytes: xdr.lookup("ScBytes"), + str: xdr.lookup("ScString"), + sym: xdr.lookup("ScSymbol"), + vec: xdr.option(xdr.lookup("ScVec")), + map: xdr.option(xdr.lookup("ScMap")), + exec: xdr.lookup("ScContractExecutable"), address: xdr.lookup("ScAddress"), - nonceAddress: xdr.lookup("ScAddress"), + nonceKey: xdr.lookup("ScNonceKey"), }, }); +// === xdr source ============================================================ +// +// struct SCMapEntry +// { +// SCVal key; +// SCVal val; +// }; +// +// =========================================================================== +xdr.struct("ScMapEntry", [ + ["key", xdr.lookup("ScVal")], + ["val", xdr.lookup("ScVal")], +]); + // === xdr source ============================================================ // // enum SCEnvMetaKind @@ -8760,19 +8808,23 @@ xdr.const("SC_SPEC_DOC_LIMIT", 1024); // SC_SPEC_TYPE_VAL = 0, // // // Types with no parameters. -// SC_SPEC_TYPE_U32 = 1, -// SC_SPEC_TYPE_I32 = 2, -// SC_SPEC_TYPE_U64 = 3, -// SC_SPEC_TYPE_I64 = 4, -// SC_SPEC_TYPE_U128 = 5, -// SC_SPEC_TYPE_I128 = 6, -// SC_SPEC_TYPE_BOOL = 7, -// SC_SPEC_TYPE_SYMBOL = 8, -// SC_SPEC_TYPE_BITSET = 9, -// SC_SPEC_TYPE_STATUS = 10, -// SC_SPEC_TYPE_BYTES = 11, -// SC_SPEC_TYPE_INVOKER = 12, -// SC_SPEC_TYPE_ADDRESS = 13, +// SC_SPEC_TYPE_BOOL = 1, +// SC_SPEC_TYPE_VOID = 2, +// SC_SPEC_TYPE_STATUS = 3, +// SC_SPEC_TYPE_U32 = 4, +// SC_SPEC_TYPE_I32 = 5, +// SC_SPEC_TYPE_U64 = 6, +// SC_SPEC_TYPE_I64 = 7, +// SC_SPEC_TYPE_TIMEPOINT = 8, +// SC_SPEC_TYPE_DURATION = 9, +// SC_SPEC_TYPE_U128 = 10, +// SC_SPEC_TYPE_I128 = 11, +// SC_SPEC_TYPE_U256 = 12, +// SC_SPEC_TYPE_I256 = 13, +// SC_SPEC_TYPE_BYTES = 14, +// SC_SPEC_TYPE_STRING = 16, +// SC_SPEC_TYPE_SYMBOL = 17, +// SC_SPEC_TYPE_ADDRESS = 19, // // // Types with parameters. // SC_SPEC_TYPE_OPTION = 1000, @@ -8790,19 +8842,23 @@ xdr.const("SC_SPEC_DOC_LIMIT", 1024); // =========================================================================== xdr.enum("ScSpecType", { scSpecTypeVal: 0, - scSpecTypeU32: 1, - scSpecTypeI32: 2, - scSpecTypeU64: 3, - scSpecTypeI64: 4, - scSpecTypeU128: 5, - scSpecTypeI128: 6, - scSpecTypeBool: 7, - scSpecTypeSymbol: 8, - scSpecTypeBitset: 9, - scSpecTypeStatus: 10, - scSpecTypeBytes: 11, - scSpecTypeInvoker: 12, - scSpecTypeAddress: 13, + scSpecTypeBool: 1, + scSpecTypeVoid: 2, + scSpecTypeStatus: 3, + scSpecTypeU32: 4, + scSpecTypeI32: 5, + scSpecTypeU64: 6, + scSpecTypeI64: 7, + scSpecTypeTimepoint: 8, + scSpecTypeDuration: 9, + scSpecTypeU128: 10, + scSpecTypeI128: 11, + scSpecTypeU256: 12, + scSpecTypeI256: 13, + scSpecTypeBytes: 14, + scSpecTypeString: 16, + scSpecTypeSymbol: 17, + scSpecTypeAddress: 19, scSpecTypeOption: 1000, scSpecTypeResult: 1001, scSpecTypeVec: 1002, @@ -8918,17 +8974,22 @@ xdr.struct("ScSpecTypeUdt", [ // union SCSpecTypeDef switch (SCSpecType type) // { // case SC_SPEC_TYPE_VAL: +// case SC_SPEC_TYPE_BOOL: +// case SC_SPEC_TYPE_VOID: +// case SC_SPEC_TYPE_STATUS: +// case SC_SPEC_TYPE_U32: +// case SC_SPEC_TYPE_I32: // case SC_SPEC_TYPE_U64: // case SC_SPEC_TYPE_I64: +// case SC_SPEC_TYPE_TIMEPOINT: +// case SC_SPEC_TYPE_DURATION: // case SC_SPEC_TYPE_U128: // case SC_SPEC_TYPE_I128: -// case SC_SPEC_TYPE_U32: -// case SC_SPEC_TYPE_I32: -// case SC_SPEC_TYPE_BOOL: -// case SC_SPEC_TYPE_SYMBOL: -// case SC_SPEC_TYPE_BITSET: -// case SC_SPEC_TYPE_STATUS: +// case SC_SPEC_TYPE_U256: +// case SC_SPEC_TYPE_I256: // case SC_SPEC_TYPE_BYTES: +// case SC_SPEC_TYPE_STRING: +// case SC_SPEC_TYPE_SYMBOL: // case SC_SPEC_TYPE_ADDRESS: // void; // case SC_SPEC_TYPE_OPTION: @@ -8955,17 +9016,22 @@ xdr.union("ScSpecTypeDef", { switchName: "type", switches: [ ["scSpecTypeVal", xdr.void()], + ["scSpecTypeBool", xdr.void()], + ["scSpecTypeVoid", xdr.void()], + ["scSpecTypeStatus", xdr.void()], + ["scSpecTypeU32", xdr.void()], + ["scSpecTypeI32", xdr.void()], ["scSpecTypeU64", xdr.void()], ["scSpecTypeI64", xdr.void()], + ["scSpecTypeTimepoint", xdr.void()], + ["scSpecTypeDuration", xdr.void()], ["scSpecTypeU128", xdr.void()], ["scSpecTypeI128", xdr.void()], - ["scSpecTypeU32", xdr.void()], - ["scSpecTypeI32", xdr.void()], - ["scSpecTypeBool", xdr.void()], - ["scSpecTypeSymbol", xdr.void()], - ["scSpecTypeBitset", xdr.void()], - ["scSpecTypeStatus", xdr.void()], + ["scSpecTypeU256", xdr.void()], + ["scSpecTypeI256", xdr.void()], ["scSpecTypeBytes", xdr.void()], + ["scSpecTypeString", xdr.void()], + ["scSpecTypeSymbol", xdr.void()], ["scSpecTypeAddress", xdr.void()], ["scSpecTypeOption", "option"], ["scSpecTypeResult", "result"], diff --git a/test/unit/address_test.js b/test/unit/address_test.js index d43e5b5d..88f1f877 100644 --- a/test/unit/address_test.js +++ b/test/unit/address_test.js @@ -47,6 +47,50 @@ describe('Address', function() { 'CAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABSC4' ); }); + + describe('.fromScAddress', function() { + it('creates an Address object for accounts', function() { + let scAddress = StellarBase.xdr.ScAddress.scAddressTypeAccount( + StellarBase.xdr.PublicKey.publicKeyTypeEd25519( + StellarBase.StrKey.decodeEd25519PublicKey(ACCOUNT) + ) + ); + let account = StellarBase.Address.fromScAddress(scAddress); + expect(account.toString()).to.equal(ACCOUNT); + }); + + it('creates an Address object for contracts', function() { + let scAddress = StellarBase.xdr.ScAddress.scAddressTypeContract( + StellarBase.StrKey.decodeContract(CONTRACT) + ); + let contract = StellarBase.Address.fromScAddress(scAddress); + expect(contract.toString()).to.equal(CONTRACT); + }); + }); + + describe('.fromScVal', function() { + it('creates an Address object for accounts', function() { + let scVal = StellarBase.xdr.ScVal.scvAddress( + StellarBase.xdr.ScAddress.scAddressTypeAccount( + StellarBase.xdr.PublicKey.publicKeyTypeEd25519( + StellarBase.StrKey.decodeEd25519PublicKey(ACCOUNT) + ) + ) + ); + let account = StellarBase.Address.fromScVal(scVal); + expect(account.toString()).to.equal(ACCOUNT); + }); + + it('creates an Address object for contracts', function() { + let scVal = StellarBase.xdr.ScVal.scvAddress( + StellarBase.xdr.ScAddress.scAddressTypeContract( + StellarBase.StrKey.decodeContract(CONTRACT) + ) + ); + let contract = StellarBase.Address.fromScVal(scVal); + expect(contract.toString()).to.equal(CONTRACT); + }); + }); }); describe('.toScAddress', function() { @@ -74,7 +118,7 @@ describe('Address', function() { const a = new StellarBase.Address(ACCOUNT); const s = a.toScVal(); expect(s).to.be.instanceof(StellarBase.xdr.ScVal); - expect(s.obj().address()).to.deep.equal(a.toScAddress()); + expect(s.address()).to.deep.equal(a.toScAddress()); }); }); diff --git a/test/unit/contract_test.js b/test/unit/contract_test.js index 9310c4b6..5d0d1778 100644 --- a/test/unit/contract_test.js +++ b/test/unit/contract_test.js @@ -11,9 +11,7 @@ describe('Contract.call', function() { let expected = new StellarBase.xdr.LedgerKey.contractData( new StellarBase.xdr.LedgerKeyContractData({ contractId: Buffer.from(contractId, 'hex'), - key: StellarBase.xdr.ScVal.scvStatic( - StellarBase.xdr.ScStatic.scsLedgerKeyContractCode() - ) + key: StellarBase.xdr.ScVal.scvLedgerKeyContractExecutable() }) ) .toXDR() diff --git a/types/index.d.ts b/types/index.d.ts index a18c90ae..d0540ec0 100644 --- a/types/index.d.ts +++ b/types/index.d.ts @@ -17,9 +17,12 @@ export class Address { static fromString(address: string): Address; static account(buffer: Buffer): Address; static contract(buffer: Buffer): Address; + static fromScVal(scVal: xdr.ScVal): Address; + static fromScAddress(scAddress: xdr.ScAddress): Address; toString(): string; toScVal(): xdr.ScVal; toScAddress(): xdr.ScAddress; + toBuffer(): Buffer; } export class Contract { diff --git a/types/next.d.ts b/types/next.d.ts index 606c8547..5234e45c 100644 --- a/types/next.d.ts +++ b/types/next.d.ts @@ -1794,50 +1794,96 @@ export namespace xdr { class ScValType { readonly name: - | 'scvU63' + | 'scvBool' + | 'scvVoid' + | 'scvStatus' | 'scvU32' | 'scvI32' - | 'scvStatic' - | 'scvObject' + | 'scvU64' + | 'scvI64' + | 'scvTimepoint' + | 'scvDuration' + | 'scvU128' + | 'scvI128' + | 'scvU256' + | 'scvI256' + | 'scvBytes' + | 'scvString' | 'scvSymbol' - | 'scvBitset' - | 'scvStatus'; + | 'scvVec' + | 'scvMap' + | 'scvContractExecutable' + | 'scvAddress' + | 'scvLedgerKeyContractExecutable' + | 'scvLedgerKeyNonce'; - readonly value: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7; + readonly value: + | 0 + | 1 + | 2 + | 3 + | 4 + | 5 + | 6 + | 7 + | 8 + | 9 + | 10 + | 11 + | 12 + | 13 + | 14 + | 15 + | 16 + | 17 + | 18 + | 19 + | 20 + | 21; + + static scvBool(): ScValType; - static scvU63(): ScValType; + static scvVoid(): ScValType; + + static scvStatus(): ScValType; static scvU32(): ScValType; static scvI32(): ScValType; - static scvStatic(): ScValType; + static scvU64(): ScValType; - static scvObject(): ScValType; + static scvI64(): ScValType; - static scvSymbol(): ScValType; + static scvTimepoint(): ScValType; - static scvBitset(): ScValType; + static scvDuration(): ScValType; - static scvStatus(): ScValType; - } + static scvU128(): ScValType; - class ScStatic { - readonly name: - | 'scsVoid' - | 'scsTrue' - | 'scsFalse' - | 'scsLedgerKeyContractCode'; + static scvI128(): ScValType; - readonly value: 0 | 1 | 2 | 3; + static scvU256(): ScValType; + + static scvI256(): ScValType; + + static scvBytes(): ScValType; + + static scvString(): ScValType; + + static scvSymbol(): ScValType; + + static scvVec(): ScValType; - static scsVoid(): ScStatic; + static scvMap(): ScValType; - static scsTrue(): ScStatic; + static scvContractExecutable(): ScValType; - static scsFalse(): ScStatic; + static scvAddress(): ScValType; - static scsLedgerKeyContractCode(): ScStatic; + static scvLedgerKeyContractExecutable(): ScValType; + + static scvLedgerKeyNonce(): ScValType; } class ScStatusType { @@ -2110,50 +2156,14 @@ export namespace xdr { static unknownErrorXdr(): ScUnknownErrorCode; } - class ScObjectType { - readonly name: - | 'scoVec' - | 'scoMap' - | 'scoU64' - | 'scoI64' - | 'scoU128' - | 'scoI128' - | 'scoBytes' - | 'scoContractCode' - | 'scoAddress' - | 'scoNonceKey'; - - readonly value: 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9; - - static scoVec(): ScObjectType; - - static scoMap(): ScObjectType; - - static scoU64(): ScObjectType; - - static scoI64(): ScObjectType; - - static scoU128(): ScObjectType; - - static scoI128(): ScObjectType; - - static scoBytes(): ScObjectType; - - static scoContractCode(): ScObjectType; - - static scoAddress(): ScObjectType; - - static scoNonceKey(): ScObjectType; - } - - class ScContractCodeType { - readonly name: 'sccontractCodeWasmRef' | 'sccontractCodeToken'; + class ScContractExecutableType { + readonly name: 'sccontractExecutableWasmRef' | 'sccontractExecutableToken'; readonly value: 0 | 1; - static sccontractCodeWasmRef(): ScContractCodeType; + static sccontractExecutableWasmRef(): ScContractExecutableType; - static sccontractCodeToken(): ScContractCodeType; + static sccontractExecutableToken(): ScContractExecutableType; } class ScAddressType { @@ -2177,18 +2187,22 @@ export namespace xdr { class ScSpecType { readonly name: | 'scSpecTypeVal' + | 'scSpecTypeBool' + | 'scSpecTypeVoid' + | 'scSpecTypeStatus' | 'scSpecTypeU32' | 'scSpecTypeI32' | 'scSpecTypeU64' | 'scSpecTypeI64' + | 'scSpecTypeTimepoint' + | 'scSpecTypeDuration' | 'scSpecTypeU128' | 'scSpecTypeI128' - | 'scSpecTypeBool' - | 'scSpecTypeSymbol' - | 'scSpecTypeBitset' - | 'scSpecTypeStatus' + | 'scSpecTypeU256' + | 'scSpecTypeI256' | 'scSpecTypeBytes' - | 'scSpecTypeInvoker' + | 'scSpecTypeString' + | 'scSpecTypeSymbol' | 'scSpecTypeAddress' | 'scSpecTypeOption' | 'scSpecTypeResult' @@ -2214,6 +2228,10 @@ export namespace xdr { | 11 | 12 | 13 + | 14 + | 16 + | 17 + | 19 | 1000 | 1001 | 1002 @@ -2225,6 +2243,12 @@ export namespace xdr { static scSpecTypeVal(): ScSpecType; + static scSpecTypeBool(): ScSpecType; + + static scSpecTypeVoid(): ScSpecType; + + static scSpecTypeStatus(): ScSpecType; + static scSpecTypeU32(): ScSpecType; static scSpecTypeI32(): ScSpecType; @@ -2233,21 +2257,23 @@ export namespace xdr { static scSpecTypeI64(): ScSpecType; - static scSpecTypeU128(): ScSpecType; + static scSpecTypeTimepoint(): ScSpecType; - static scSpecTypeI128(): ScSpecType; + static scSpecTypeDuration(): ScSpecType; - static scSpecTypeBool(): ScSpecType; + static scSpecTypeU128(): ScSpecType; - static scSpecTypeSymbol(): ScSpecType; + static scSpecTypeI128(): ScSpecType; - static scSpecTypeBitset(): ScSpecType; + static scSpecTypeU256(): ScSpecType; - static scSpecTypeStatus(): ScSpecType; + static scSpecTypeI256(): ScSpecType; static scSpecTypeBytes(): ScSpecType; - static scSpecTypeInvoker(): ScSpecType; + static scSpecTypeString(): ScSpecType; + + static scSpecTypeSymbol(): ScSpecType; static scSpecTypeAddress(): ScSpecType; @@ -2309,10 +2335,6 @@ export namespace xdr { type SequenceNumber = Int64; - type TimePoint = Uint64; - - type Duration = Uint64; - const DataValue: VarOpaque; type PoolId = typeof Hash; @@ -2347,6 +2369,10 @@ export namespace xdr { class Int64 extends Hyper {} + type TimePoint = Uint64; + + type Duration = Uint64; + const Signature: VarOpaque; const SignatureHint: Opaque; @@ -2355,12 +2381,16 @@ export namespace xdr { type AccountId = PublicKey; - const ScSymbol: XDRString; - const ScVec: XDRArray; const ScMap: XDRArray; + const ScBytes: VarOpaque; + + const ScString: XDRString; + + const ScSymbol: XDRString; + class ScpBallot { constructor(attributes: { counter: number; value: Buffer }); @@ -6464,11 +6494,14 @@ export namespace xdr { } class CreateContractArgs { - constructor(attributes: { contractId: ContractId; source: ScContractCode }); + constructor(attributes: { + contractId: ContractId; + source: ScContractExecutable; + }); contractId(value?: ContractId): ContractId; - source(value?: ScContractCode): ScContractCode; + source(value?: ScContractExecutable): ScContractExecutable; toXDR(format?: 'raw'): Buffer; @@ -6895,13 +6928,13 @@ export namespace xdr { class HashIdPreimageCreateContractArgs { constructor(attributes: { networkId: Buffer; - source: ScContractCode; + source: ScContractExecutable; salt: Buffer; }); networkId(value?: Buffer): Buffer; - source(value?: ScContractCode): ScContractCode; + source(value?: ScContractExecutable): ScContractExecutable; salt(value?: Buffer): Buffer; @@ -7874,56 +7907,82 @@ export namespace xdr { static validateXDR(input: string, format: 'hex' | 'base64'): boolean; } - class ScMapEntry { - constructor(attributes: { key: ScVal; val: ScVal }); + class Int128Parts { + constructor(attributes: { lo: Uint64; hi: Uint64 }); - key(value?: ScVal): ScVal; + lo(value?: Uint64): Uint64; - val(value?: ScVal): ScVal; + hi(value?: Uint64): Uint64; toXDR(format?: 'raw'): Buffer; toXDR(format: 'hex' | 'base64'): string; - static read(io: Buffer): ScMapEntry; + static read(io: Buffer): Int128Parts; - static write(value: ScMapEntry, io: Buffer): void; + static write(value: Int128Parts, io: Buffer): void; - static isValid(value: ScMapEntry): boolean; + static isValid(value: Int128Parts): boolean; - static toXDR(value: ScMapEntry): Buffer; + static toXDR(value: Int128Parts): Buffer; - static fromXDR(input: Buffer, format?: 'raw'): ScMapEntry; + static fromXDR(input: Buffer, format?: 'raw'): Int128Parts; - static fromXDR(input: string, format: 'hex' | 'base64'): ScMapEntry; + static fromXDR(input: string, format: 'hex' | 'base64'): Int128Parts; static validateXDR(input: Buffer, format?: 'raw'): boolean; static validateXDR(input: string, format: 'hex' | 'base64'): boolean; } - class Int128Parts { - constructor(attributes: { lo: Uint64; hi: Uint64 }); + class ScNonceKey { + constructor(attributes: { nonceAddress: ScAddress }); - lo(value?: Uint64): Uint64; + nonceAddress(value?: ScAddress): ScAddress; - hi(value?: Uint64): Uint64; + toXDR(format?: 'raw'): Buffer; + + toXDR(format: 'hex' | 'base64'): string; + + static read(io: Buffer): ScNonceKey; + + static write(value: ScNonceKey, io: Buffer): void; + + static isValid(value: ScNonceKey): boolean; + + static toXDR(value: ScNonceKey): Buffer; + + static fromXDR(input: Buffer, format?: 'raw'): ScNonceKey; + + static fromXDR(input: string, format: 'hex' | 'base64'): ScNonceKey; + + static validateXDR(input: Buffer, format?: 'raw'): boolean; + + static validateXDR(input: string, format: 'hex' | 'base64'): boolean; + } + + class ScMapEntry { + constructor(attributes: { key: ScVal; val: ScVal }); + + key(value?: ScVal): ScVal; + + val(value?: ScVal): ScVal; toXDR(format?: 'raw'): Buffer; toXDR(format: 'hex' | 'base64'): string; - static read(io: Buffer): Int128Parts; + static read(io: Buffer): ScMapEntry; - static write(value: Int128Parts, io: Buffer): void; + static write(value: ScMapEntry, io: Buffer): void; - static isValid(value: Int128Parts): boolean; + static isValid(value: ScMapEntry): boolean; - static toXDR(value: Int128Parts): Buffer; + static toXDR(value: ScMapEntry): Buffer; - static fromXDR(input: Buffer, format?: 'raw'): Int128Parts; + static fromXDR(input: Buffer, format?: 'raw'): ScMapEntry; - static fromXDR(input: string, format: 'hex' | 'base64'): Int128Parts; + static fromXDR(input: string, format: 'hex' | 'base64'): ScMapEntry; static validateXDR(input: Buffer, format?: 'raw'): boolean; @@ -12885,82 +12944,14 @@ export namespace xdr { static validateXDR(input: string, format: 'hex' | 'base64'): boolean; } - class ScVal { - switch(): ScValType; - - u63(value?: Int64): Int64; - - u32(value?: number): number; - - i32(value?: number): number; - - ic(value?: ScStatic): ScStatic; - - obj(value?: null | ScObject): null | ScObject; - - sym(value?: string | Buffer): string | Buffer; - - bits(value?: Uint64): Uint64; - - status(value?: ScStatus): ScStatus; - - static scvU63(value: Int64): ScVal; - - static scvU32(value: number): ScVal; - - static scvI32(value: number): ScVal; - - static scvStatic(value: ScStatic): ScVal; - - static scvObject(value: null | ScObject): ScVal; - - static scvSymbol(value: string | Buffer): ScVal; - - static scvBitset(value: Uint64): ScVal; - - static scvStatus(value: ScStatus): ScVal; - - value(): - | Int64 - | number - | number - | ScStatic - | null - | ScObject - | string - | Buffer - | Uint64 - | ScStatus; - - toXDR(format?: 'raw'): Buffer; - - toXDR(format: 'hex' | 'base64'): string; - - static read(io: Buffer): ScVal; - - static write(value: ScVal, io: Buffer): void; - - static isValid(value: ScVal): boolean; - - static toXDR(value: ScVal): Buffer; - - static fromXDR(input: Buffer, format?: 'raw'): ScVal; - - static fromXDR(input: string, format: 'hex' | 'base64'): ScVal; - - static validateXDR(input: Buffer, format?: 'raw'): boolean; - - static validateXDR(input: string, format: 'hex' | 'base64'): boolean; - } - - class ScContractCode { - switch(): ScContractCodeType; + class ScContractExecutable { + switch(): ScContractExecutableType; wasmId(value?: Buffer): Buffer; - static sccontractCodeWasmRef(value: Buffer): ScContractCode; + static sccontractExecutableWasmRef(value: Buffer): ScContractExecutable; - static sccontractCodeToken(): ScContractCode; + static sccontractExecutableToken(): ScContractExecutable; value(): Buffer | void; @@ -12968,17 +12959,20 @@ export namespace xdr { toXDR(format: 'hex' | 'base64'): string; - static read(io: Buffer): ScContractCode; + static read(io: Buffer): ScContractExecutable; - static write(value: ScContractCode, io: Buffer): void; + static write(value: ScContractExecutable, io: Buffer): void; - static isValid(value: ScContractCode): boolean; + static isValid(value: ScContractExecutable): boolean; - static toXDR(value: ScContractCode): Buffer; + static toXDR(value: ScContractExecutable): Buffer; - static fromXDR(input: Buffer, format?: 'raw'): ScContractCode; + static fromXDR(input: Buffer, format?: 'raw'): ScContractExecutable; - static fromXDR(input: string, format: 'hex' | 'base64'): ScContractCode; + static fromXDR( + input: string, + format: 'hex' | 'base64' + ): ScContractExecutable; static validateXDR(input: Buffer, format?: 'raw'): boolean; @@ -13019,76 +13013,135 @@ export namespace xdr { static validateXDR(input: string, format: 'hex' | 'base64'): boolean; } - class ScObject { - switch(): ScObjectType; + class ScVal { + switch(): ScValType; - vec(value?: ScVal[]): ScVal[]; + b(value?: boolean): boolean; - map(value?: ScMapEntry[]): ScMapEntry[]; + error(value?: ScStatus): ScStatus; + + u32(value?: number): number; + + i32(value?: number): number; u64(value?: Uint64): Uint64; i64(value?: Int64): Int64; + timepoint(value?: TimePoint): TimePoint; + + duration(value?: Duration): Duration; + u128(value?: Int128Parts): Int128Parts; i128(value?: Int128Parts): Int128Parts; - bin(value?: Buffer): Buffer; + u256(value?: Buffer): Buffer; + + i256(value?: Buffer): Buffer; + + bytes(value?: Buffer): Buffer; + + str(value?: string | Buffer): string | Buffer; + + sym(value?: string | Buffer): string | Buffer; + + vec(value?: null | ScVal[]): null | ScVal[]; + + map(value?: null | ScMapEntry[]): null | ScMapEntry[]; - contractCode(value?: ScContractCode): ScContractCode; + exec(value?: ScContractExecutable): ScContractExecutable; address(value?: ScAddress): ScAddress; - nonceAddress(value?: ScAddress): ScAddress; + nonceKey(value?: ScNonceKey): ScNonceKey; - static scoVec(value: ScVal[]): ScObject; + static scvBool(value: boolean): ScVal; - static scoMap(value: ScMapEntry[]): ScObject; + static scvVoid(): ScVal; + + static scvStatus(value: ScStatus): ScVal; + + static scvU32(value: number): ScVal; + + static scvI32(value: number): ScVal; - static scoU64(value: Uint64): ScObject; + static scvU64(value: Uint64): ScVal; - static scoI64(value: Int64): ScObject; + static scvI64(value: Int64): ScVal; - static scoU128(value: Int128Parts): ScObject; + static scvTimepoint(value: TimePoint): ScVal; - static scoI128(value: Int128Parts): ScObject; + static scvDuration(value: Duration): ScVal; - static scoBytes(value: Buffer): ScObject; + static scvU128(value: Int128Parts): ScVal; - static scoContractCode(value: ScContractCode): ScObject; + static scvI128(value: Int128Parts): ScVal; - static scoAddress(value: ScAddress): ScObject; + static scvU256(value: Buffer): ScVal; - static scoNonceKey(value: ScAddress): ScObject; + static scvI256(value: Buffer): ScVal; + + static scvBytes(value: Buffer): ScVal; + + static scvString(value: string | Buffer): ScVal; + + static scvSymbol(value: string | Buffer): ScVal; + + static scvVec(value: null | ScVal[]): ScVal; + + static scvMap(value: null | ScMapEntry[]): ScVal; + + static scvContractExecutable(value: ScContractExecutable): ScVal; + + static scvAddress(value: ScAddress): ScVal; + + static scvLedgerKeyContractExecutable(): ScVal; + + static scvLedgerKeyNonce(value: ScNonceKey): ScVal; value(): - | ScVal[] - | ScMapEntry[] + | boolean + | ScStatus + | number + | number | Uint64 | Int64 + | TimePoint + | Duration | Int128Parts | Int128Parts | Buffer - | ScContractCode + | Buffer + | Buffer + | string + | Buffer + | string + | Buffer + | null + | ScVal[] + | null + | ScMapEntry[] + | ScContractExecutable | ScAddress - | ScAddress; + | ScNonceKey + | void; toXDR(format?: 'raw'): Buffer; toXDR(format: 'hex' | 'base64'): string; - static read(io: Buffer): ScObject; + static read(io: Buffer): ScVal; - static write(value: ScObject, io: Buffer): void; + static write(value: ScVal, io: Buffer): void; - static isValid(value: ScObject): boolean; + static isValid(value: ScVal): boolean; - static toXDR(value: ScObject): Buffer; + static toXDR(value: ScVal): Buffer; - static fromXDR(input: Buffer, format?: 'raw'): ScObject; + static fromXDR(input: Buffer, format?: 'raw'): ScVal; - static fromXDR(input: string, format: 'hex' | 'base64'): ScObject; + static fromXDR(input: string, format: 'hex' | 'base64'): ScVal; static validateXDR(input: Buffer, format?: 'raw'): boolean; @@ -13146,28 +13199,38 @@ export namespace xdr { static scSpecTypeVal(): ScSpecTypeDef; - static scSpecTypeU64(): ScSpecTypeDef; + static scSpecTypeBool(): ScSpecTypeDef; - static scSpecTypeI64(): ScSpecTypeDef; + static scSpecTypeVoid(): ScSpecTypeDef; - static scSpecTypeU128(): ScSpecTypeDef; - - static scSpecTypeI128(): ScSpecTypeDef; + static scSpecTypeStatus(): ScSpecTypeDef; static scSpecTypeU32(): ScSpecTypeDef; static scSpecTypeI32(): ScSpecTypeDef; - static scSpecTypeBool(): ScSpecTypeDef; + static scSpecTypeU64(): ScSpecTypeDef; - static scSpecTypeSymbol(): ScSpecTypeDef; + static scSpecTypeI64(): ScSpecTypeDef; - static scSpecTypeBitset(): ScSpecTypeDef; + static scSpecTypeTimepoint(): ScSpecTypeDef; - static scSpecTypeStatus(): ScSpecTypeDef; + static scSpecTypeDuration(): ScSpecTypeDef; + + static scSpecTypeU128(): ScSpecTypeDef; + + static scSpecTypeI128(): ScSpecTypeDef; + + static scSpecTypeU256(): ScSpecTypeDef; + + static scSpecTypeI256(): ScSpecTypeDef; static scSpecTypeBytes(): ScSpecTypeDef; + static scSpecTypeString(): ScSpecTypeDef; + + static scSpecTypeSymbol(): ScSpecTypeDef; + static scSpecTypeAddress(): ScSpecTypeDef; static scSpecTypeOption(value: ScSpecTypeOption): ScSpecTypeDef; diff --git a/xdr/next/Stellar-contract-spec.x b/xdr/next/Stellar-contract-spec.x index 47647a13..8431e226 100644 --- a/xdr/next/Stellar-contract-spec.x +++ b/xdr/next/Stellar-contract-spec.x @@ -17,19 +17,23 @@ enum SCSpecType SC_SPEC_TYPE_VAL = 0, // Types with no parameters. - SC_SPEC_TYPE_U32 = 1, - SC_SPEC_TYPE_I32 = 2, - SC_SPEC_TYPE_U64 = 3, - SC_SPEC_TYPE_I64 = 4, - SC_SPEC_TYPE_U128 = 5, - SC_SPEC_TYPE_I128 = 6, - SC_SPEC_TYPE_BOOL = 7, - SC_SPEC_TYPE_SYMBOL = 8, - SC_SPEC_TYPE_BITSET = 9, - SC_SPEC_TYPE_STATUS = 10, - SC_SPEC_TYPE_BYTES = 11, - SC_SPEC_TYPE_INVOKER = 12, - SC_SPEC_TYPE_ADDRESS = 13, + SC_SPEC_TYPE_BOOL = 1, + SC_SPEC_TYPE_VOID = 2, + SC_SPEC_TYPE_STATUS = 3, + SC_SPEC_TYPE_U32 = 4, + SC_SPEC_TYPE_I32 = 5, + SC_SPEC_TYPE_U64 = 6, + SC_SPEC_TYPE_I64 = 7, + SC_SPEC_TYPE_TIMEPOINT = 8, + SC_SPEC_TYPE_DURATION = 9, + SC_SPEC_TYPE_U128 = 10, + SC_SPEC_TYPE_I128 = 11, + SC_SPEC_TYPE_U256 = 12, + SC_SPEC_TYPE_I256 = 13, + SC_SPEC_TYPE_BYTES = 14, + SC_SPEC_TYPE_STRING = 16, + SC_SPEC_TYPE_SYMBOL = 17, + SC_SPEC_TYPE_ADDRESS = 19, // Types with parameters. SC_SPEC_TYPE_OPTION = 1000, @@ -89,17 +93,22 @@ struct SCSpecTypeUDT union SCSpecTypeDef switch (SCSpecType type) { case SC_SPEC_TYPE_VAL: +case SC_SPEC_TYPE_BOOL: +case SC_SPEC_TYPE_VOID: +case SC_SPEC_TYPE_STATUS: +case SC_SPEC_TYPE_U32: +case SC_SPEC_TYPE_I32: case SC_SPEC_TYPE_U64: case SC_SPEC_TYPE_I64: +case SC_SPEC_TYPE_TIMEPOINT: +case SC_SPEC_TYPE_DURATION: case SC_SPEC_TYPE_U128: case SC_SPEC_TYPE_I128: -case SC_SPEC_TYPE_U32: -case SC_SPEC_TYPE_I32: -case SC_SPEC_TYPE_BOOL: -case SC_SPEC_TYPE_SYMBOL: -case SC_SPEC_TYPE_BITSET: -case SC_SPEC_TYPE_STATUS: +case SC_SPEC_TYPE_U256: +case SC_SPEC_TYPE_I256: case SC_SPEC_TYPE_BYTES: +case SC_SPEC_TYPE_STRING: +case SC_SPEC_TYPE_SYMBOL: case SC_SPEC_TYPE_ADDRESS: void; case SC_SPEC_TYPE_OPTION: diff --git a/xdr/next/Stellar-contract.x b/xdr/next/Stellar-contract.x index 6a0bc7ad..66040e25 100644 --- a/xdr/next/Stellar-contract.x +++ b/xdr/next/Stellar-contract.x @@ -5,67 +5,73 @@ % #include "xdr/Stellar-types.h" namespace stellar { -/* - * Smart Contracts deal in SCVals. These are a (dynamic) disjoint union - * between several possible variants, to allow storing generic SCVals in - * generic data structures and passing them in and out of languages that - * have simple or dynamic type systems. - * - * SCVals are (in WASM's case) stored in a tagged 64-bit word encoding. Most - * signed 64-bit values in Stellar are actually signed positive values - * (sequence numbers, timestamps, amounts), so we don't need the high bit - * and can get away with 1-bit tagging and store them as "unsigned 63bit", - * (u63) separate from everything else. - * - * We actually reserve the low _four_ bits, leaving 3 bits for 8 cases of - * "non-u63 values", some of which have substructure of their own. - * - * 0x_NNNN_NNNN_NNNN_NNNX - u63, for any even X - * 0x_0000_000N_NNNN_NNN1 - u32 - * 0x_0000_000N_NNNN_NNN3 - i32 - * 0x_NNNN_NNNN_NNNN_NNN5 - static: void, true, false, ... (SCS_*) - * 0x_IIII_IIII_TTTT_TTT7 - object: 32-bit index I, 28-bit type code T - * 0x_NNNN_NNNN_NNNN_NNN9 - symbol: up to 10 6-bit identifier characters - * 0x_NNNN_NNNN_NNNN_NNNb - bitset: up to 60 bits - * 0x_CCCC_CCCC_TTTT_TTTd - status: 32-bit code C, 28-bit type code T - * 0x_NNNN_NNNN_NNNN_NNNf - reserved - * - * Up here in XDR we have variable-length tagged disjoint unions but no - * bit-level packing, so we can be more explicit in their structure, at the - * cost of spending more than 64 bits to encode many cases, and also having - * to convert. It's a little non-obvious at the XDR level why there's a - * split between SCVal and SCObject given that they are both immutable types - * with value semantics; but the split reflects the split that happens in - * the implementation, and marks a place where different implementations of - * immutability (CoW, structural sharing, etc.) will likely occur. - */ - -// A symbol is up to 10 chars drawn from [a-zA-Z0-9_], which can be packed -// into 60 bits with a 6-bit-per-character code, usable as a small key type -// to specify function, argument, tx-local environment and map entries -// efficiently. -typedef string SCSymbol<10>; + +// We fix a maximum of 128 value types in the system for two reasons: we want to +// keep the codes relatively small (<= 8 bits) when bit-packing values into a +// u64 at the environment interface level, so that we keep many bits for +// payloads (small strings, small numeric values, object handles); and then we +// actually want to go one step further and ensure (for code-size) that our +// codes fit in a single ULEB128-code byte, which means we can only use 7 bits. +// +// We also reserve several type codes from this space because we want to _reuse_ +// the SCValType codes at the environment interface level (or at least not +// exceed its number-space) but there are more types at that level, assigned to +// optimizations/special case representations of values abstract at this level. enum SCValType { - SCV_U63 = 0, - SCV_U32 = 1, - SCV_I32 = 2, - SCV_STATIC = 3, - SCV_OBJECT = 4, - SCV_SYMBOL = 5, - SCV_BITSET = 6, - SCV_STATUS = 7 -}; + SCV_BOOL = 0, + SCV_VOID = 1, + SCV_STATUS = 2, -% struct SCObject; + // 32 bits is the smallest type in WASM or XDR; no need for u8/u16. + SCV_U32 = 3, + SCV_I32 = 4, -enum SCStatic -{ - SCS_VOID = 0, - SCS_TRUE = 1, - SCS_FALSE = 2, - SCS_LEDGER_KEY_CONTRACT_CODE = 3 + // 64 bits is naturally supported by both WASM and XDR also. + SCV_U64 = 5, + SCV_I64 = 6, + + // Time-related u64 subtypes with their own functions and formatting. + SCV_TIMEPOINT = 7, + SCV_DURATION = 8, + + // 128 bits is naturally supported by Rust and we use it for Soroban + // fixed-point arithmetic prices / balances / similar "quantities". These + // are represented in XDR as a pair of 2 u64s, unlike {u,i}256 which is + // represented as an array of 32 bytes. + SCV_U128 = 9, + SCV_I128 = 10, + + // 256 bits is the size of sha256 output, ed25519 keys, and the EVM machine + // word, so for interop use we include this even though it requires a small + // amount of Rust guest and/or host library code. + SCV_U256 = 11, + SCV_I256 = 12, + + // TODO: possibly allocate subtypes of i64, i128 and/or u256 for + // fixed-precision with a specific number of decimals. + + // Bytes come in 3 flavors, 2 of which have meaningfully different + // formatting and validity-checking / domain-restriction. + SCV_BYTES = 13, + SCV_STRING = 14, + SCV_SYMBOL = 15, + + // Vecs and maps are just polymorphic containers of other ScVals. + SCV_VEC = 16, + SCV_MAP = 17, + + // SCContractExecutable and SCAddressType are types that gets used separately from + // SCVal so we do not flatten their structures into separate SCVal cases. + SCV_CONTRACT_EXECUTABLE = 18, + SCV_ADDRESS = 19, + + // SCV_LEDGER_KEY_CONTRACT_EXECUTABLE and SCV_LEDGER_KEY_NONCE are unique + // symbolic SCVals used as the key for ledger entries for a contract's code + // and an address' nonce, respectively. + SCV_LEDGER_KEY_CONTRACT_EXECUTABLE = 20, + SCV_LEDGER_KEY_NONCE = 21 }; enum SCStatusType @@ -195,78 +201,28 @@ case SST_HOST_AUTH_ERROR: SCHostAuthErrorCode authCode; }; -union SCVal switch (SCValType type) -{ -case SCV_U63: - int64 u63; -case SCV_U32: - uint32 u32; -case SCV_I32: - int32 i32; -case SCV_STATIC: - SCStatic ic; -case SCV_OBJECT: - SCObject* obj; -case SCV_SYMBOL: - SCSymbol sym; -case SCV_BITSET: - uint64 bits; -case SCV_STATUS: - SCStatus status; -}; - -enum SCObjectType -{ - // We have a few objects that represent non-stellar-specific concepts - // like general-purpose maps, vectors, numbers, blobs. - - SCO_VEC = 0, - SCO_MAP = 1, - SCO_U64 = 2, - SCO_I64 = 3, - SCO_U128 = 4, - SCO_I128 = 5, - SCO_BYTES = 6, - SCO_CONTRACT_CODE = 7, - SCO_ADDRESS = 8, - SCO_NONCE_KEY = 9 - - // TODO: add more -}; - -struct SCMapEntry -{ - SCVal key; - SCVal val; +struct Int128Parts { + // Both signed and unsigned 128-bit ints + // are transported in a pair of uint64s + // to reduce the risk of sign-extension. + uint64 lo; + uint64 hi; }; -const SCVAL_LIMIT = 256000; - -typedef SCVal SCVec; -typedef SCMapEntry SCMap; - -enum SCContractCodeType +enum SCContractExecutableType { - SCCONTRACT_CODE_WASM_REF = 0, - SCCONTRACT_CODE_TOKEN = 1 + SCCONTRACT_EXECUTABLE_WASM_REF = 0, + SCCONTRACT_EXECUTABLE_TOKEN = 1 }; -union SCContractCode switch (SCContractCodeType type) +union SCContractExecutable switch (SCContractExecutableType type) { -case SCCONTRACT_CODE_WASM_REF: +case SCCONTRACT_EXECUTABLE_WASM_REF: Hash wasm_id; -case SCCONTRACT_CODE_TOKEN: +case SCCONTRACT_EXECUTABLE_TOKEN: void; }; -struct Int128Parts { - // Both signed and unsigned 128-bit ints - // are transported in a pair of uint64s - // to reduce the risk of sign-extension. - uint64 lo; - uint64 hi; -}; - enum SCAddressType { SC_ADDRESS_TYPE_ACCOUNT = 0, @@ -281,27 +237,88 @@ case SC_ADDRESS_TYPE_CONTRACT: Hash contractId; }; -union SCObject switch (SCObjectType type) +%struct SCVal; +%struct SCMapEntry; + +const SCVAL_LIMIT = 256000; +const SCSYMBOL_LIMIT = 32; + +typedef SCVal SCVec; +typedef SCMapEntry SCMap; + +typedef opaque SCBytes; +typedef string SCString; +typedef string SCSymbol; + +struct SCNonceKey { + SCAddress nonce_address; +}; + +union SCVal switch (SCValType type) { -case SCO_VEC: - SCVec vec; -case SCO_MAP: - SCMap map; -case SCO_U64: + +case SCV_BOOL: + bool b; +case SCV_VOID: + void; +case SCV_STATUS: + SCStatus error; + +case SCV_U32: + uint32 u32; +case SCV_I32: + int32 i32; + +case SCV_U64: uint64 u64; -case SCO_I64: +case SCV_I64: int64 i64; -case SCO_U128: +case SCV_TIMEPOINT: + TimePoint timepoint; +case SCV_DURATION: + Duration duration; + +case SCV_U128: Int128Parts u128; -case SCO_I128: +case SCV_I128: Int128Parts i128; -case SCO_BYTES: - opaque bin; -case SCO_CONTRACT_CODE: - SCContractCode contractCode; -case SCO_ADDRESS: + +case SCV_U256: + uint256 u256; +case SCV_I256: + uint256 i256; + +case SCV_BYTES: + SCBytes bytes; +case SCV_STRING: + SCString str; +case SCV_SYMBOL: + SCSymbol sym; + +// Vec and Map are recursive so need to live +// behind an option, due to xdrpp limitations. +case SCV_VEC: + SCVec *vec; +case SCV_MAP: + SCMap *map; + +case SCV_CONTRACT_EXECUTABLE: + SCContractExecutable exec; +case SCV_ADDRESS: SCAddress address; -case SCO_NONCE_KEY: - SCAddress nonceAddress; + +// Special SCVals reserved for system-constructed contract-data +// ledger keys, not generally usable elsewhere. +case SCV_LEDGER_KEY_CONTRACT_EXECUTABLE: + void; +case SCV_LEDGER_KEY_NONCE: + SCNonceKey nonce_key; +}; + +struct SCMapEntry +{ + SCVal key; + SCVal val; }; + } diff --git a/xdr/next/Stellar-ledger-entries.x b/xdr/next/Stellar-ledger-entries.x index 55bdfe80..d8f1b737 100644 --- a/xdr/next/Stellar-ledger-entries.x +++ b/xdr/next/Stellar-ledger-entries.x @@ -12,8 +12,6 @@ typedef opaque Thresholds[4]; typedef string string32<32>; typedef string string64<64>; typedef int64 SequenceNumber; -typedef uint64 TimePoint; -typedef uint64 Duration; typedef opaque DataValue<64>; typedef Hash PoolID; // SHA256(LiquidityPoolParameters) diff --git a/xdr/next/Stellar-transaction.x b/xdr/next/Stellar-transaction.x index 3c98faa5..2b0b0587 100644 --- a/xdr/next/Stellar-transaction.x +++ b/xdr/next/Stellar-transaction.x @@ -517,7 +517,7 @@ case CONTRACT_ID_FROM_ASSET: struct CreateContractArgs { ContractID contractID; - SCContractCode source; + SCContractExecutable source; }; union HostFunction switch (HostFunctionType type) @@ -675,7 +675,7 @@ case ENVELOPE_TYPE_CREATE_CONTRACT_ARGS: struct { Hash networkID; - SCContractCode source; + SCContractExecutable source; uint256 salt; } createContractArgs; case ENVELOPE_TYPE_CONTRACT_AUTH: diff --git a/xdr/next/Stellar-types.x b/xdr/next/Stellar-types.x index a6f9bf9c..d71bf0d4 100644 --- a/xdr/next/Stellar-types.x +++ b/xdr/next/Stellar-types.x @@ -14,6 +14,9 @@ typedef int int32; typedef unsigned hyper uint64; typedef hyper int64; +typedef uint64 TimePoint; +typedef uint64 Duration; + // An ExtensionPoint is always marshaled as a 32-bit 0 value. At a // later point, it can be replaced by a different union so as to // extend a structure.