diff --git a/examples/assets/gumball_machine.rs b/examples/assets/gumball_machine.rs index 0f3e6130..a77ad791 100644 --- a/examples/assets/gumball_machine.rs +++ b/examples/assets/gumball_machine.rs @@ -29,10 +29,10 @@ mod gumball_machine { icon_url: String ) -> (ComponentAddress, Bucket) { let (reservation, component_address) = - Runtime::allocate_component_address(Runtime::blueprint_id()); + Runtime::allocate_component_address(GumballMachine::blueprint_id()); let non_fungible_global_id = NonFungibleGlobalId::package_of_direct_caller_badge( - Runtime::blueprint_id().package_address, + GumballMachine::blueprint_id().package_address, ); let account = Blueprint::::create_advanced(OwnerRole::Fixed(rule!(require( non_fungible_global_id diff --git a/examples/assets/gumball_machine.wasm b/examples/assets/gumball_machine.wasm index 236daf5e..fa18a5b7 100755 Binary files a/examples/assets/gumball_machine.wasm and b/examples/assets/gumball_machine.wasm differ diff --git a/examples/helpers/get-network-id.ts b/examples/helpers/get-network-id.ts index c29923c8..e8e57347 100644 --- a/examples/helpers/get-network-id.ts +++ b/examples/helpers/get-network-id.ts @@ -1,6 +1,6 @@ import { RadixNetwork } from '@radixdlt/babylon-gateway-api-sdk' -export const DEFAULT_NETWORK_ID = RadixNetwork.Hammunet.toString() +export const DEFAULT_NETWORK_ID = RadixNetwork.Enkinet.toString() export const getNetworkId = () => { const urlParams = new URLSearchParams(window.location.search) diff --git a/examples/helpers/hash.spec.ts b/examples/helpers/hash.spec.ts index 495624e8..de4cdcdc 100644 --- a/examples/helpers/hash.spec.ts +++ b/examples/helpers/hash.spec.ts @@ -8,7 +8,7 @@ describe('hash', () => { join(__dirname, '../assets/gumball_machine.wasm') ).toString('hex') expect(hash(gumballMachineWasm).toString('hex')).toBe( - '0ee930dc59854bfdfe0d638b3f794c9983dddc7197cb01d2b6275042ddb9bf27' + 'a6eab9a9bf73b2beeeabb37b57fac4f83b59528ac2e59d3a84e3c932d9d8b5c1' ) }) }) diff --git a/examples/network/state.ts b/examples/network/state.ts index 1c5a0cf1..b4ce0a72 100644 --- a/examples/network/state.ts +++ b/examples/network/state.ts @@ -38,7 +38,7 @@ const getNetworkIdDefault = () => { const networkId = parseInt( urlParams.get('networkId') || localStorage.getItem('networkId') || - RadixNetwork.Hammunet.toString(), + RadixNetwork.Enkinet.toString(), 10 ) return networkId diff --git a/examples/pools/CreatePoolCard.tsx b/examples/pools/CreatePoolCard.tsx index b5d1c05b..48ec14f7 100644 --- a/examples/pools/CreatePoolCard.tsx +++ b/examples/pools/CreatePoolCard.tsx @@ -74,8 +74,7 @@ export const CreatePoolCard = () => { resources: Object.values(resourceAddresses), transactions: [ { - transactionIntentHash: - response.transaction.intent_hash_hex || '', + transactionIntentHash: response.transaction.intent_hash || '', status: response.transaction.transaction_status, }, ], diff --git a/examples/rdt/rdt.ts b/examples/rdt/rdt.ts index d0596243..c25304d8 100644 --- a/examples/rdt/rdt.ts +++ b/examples/rdt/rdt.ts @@ -37,6 +37,8 @@ const getDAppDefinitionFromLocalStorage = (): Record => { 'account_tdx_d_16996e320lnez82q6430eunaz9l3n5fnwk6eh9avrmtmj22e7m9lvl2', [RadixNetwork.Hammunet]: 'account_tdx_22_12xt9uxe39dxdfy9c23vn0qj7eaxs8p3fjjpkr8f48edsfvyk00ck3l', + [RadixNetwork.Enkinet]: + 'account_tdx_21_168ydk240yx69yl7zdz2mzkdjc3r5p6n4gwypqsype2d6d942z0tyvx', } } diff --git a/examples/rola/helpers/derive-address-from-public-key.spec.ts b/examples/rola/helpers/derive-address-from-public-key.spec.ts new file mode 100644 index 00000000..8d0eb6a1 --- /dev/null +++ b/examples/rola/helpers/derive-address-from-public-key.spec.ts @@ -0,0 +1,44 @@ +import { + deriveVirtualEcdsaSecp256k1AccountAddress, + deriveVirtualEddsaEd25519AccountAddress, + deriveVirtualIdentityAddress, +} from './derive-address-from-public-key' +import { RadixNetwork } from '@radixdlt/babylon-gateway-api-sdk' + +describe('deriveAddressFromPublicKey', () => { + it('should derive virtual identity address', async () => { + const output = deriveVirtualIdentityAddress( + '59c02cc1c4cc1eddd90907bb848c44ac1808d844476c1621ecf234cf3ed49c57', + RadixNetwork.Enkinet + ) + + const result = await output.unwrapOr(undefined) + expect(result).toEqual( + 'identity_tdx_21_12t5uwv48e5j7w368r7kjmcrw3wygfh0dtssz0u5n4hkq7qawrwrzyv' + ) + }) + + it('should derive ed25519 virtual account address', async () => { + const output = deriveVirtualEddsaEd25519AccountAddress( + '59c02cc1c4cc1eddd90907bb848c44ac1808d844476c1621ecf234cf3ed49c57', + RadixNetwork.Enkinet + ) + + const result = await output.unwrapOr(undefined) + expect(result).toEqual( + 'account_tdx_21_1285uwv48e5j7w368r7kjmcrw3wygfh0dtssz0u5n4hkq7qawthf4kn' + ) + }) + + it('should derive secp256k1 virtual account address', async () => { + const output = deriveVirtualEcdsaSecp256k1AccountAddress( + '02807797adba8d61024c186f438b7bd9c7e1260b6306d615c35faeef9da052e5e4', + RadixNetwork.Enkinet + ) + + const result = await output.unwrapOr(undefined) + expect(result).toEqual( + 'account_tdx_21_168razfxd603n87nals6us3nnzet2k9tjdk5dlyh2xdjkah3duuyyr3' + ) + }) +}) diff --git a/examples/rola/helpers/derive-address-from-public-key.ts b/examples/rola/helpers/derive-address-from-public-key.ts index fe07228b..ef0d811f 100644 --- a/examples/rola/helpers/derive-address-from-public-key.ts +++ b/examples/rola/helpers/derive-address-from-public-key.ts @@ -1,36 +1,38 @@ -import { RadixEngineToolkit } from '@radixdlt/radix-engine-toolkit' +import { PublicKey, RadixEngineToolkit } from '@radixdlt/radix-engine-toolkit' import { ResultAsync, errAsync } from 'neverthrow' import { SignedChallenge } from '../../../src' -import { Buffer } from 'buffer' -const deriveVirtualIdentityAddress = (publicKey: string, networkId: number) => +export const deriveVirtualIdentityAddress = ( + publicKey: string, + networkId: number +) => ResultAsync.fromPromise( RadixEngineToolkit.Derive.virtualIdentityAddressFromPublicKey( - { kind: 'Ed25519', publicKey: Buffer.from(publicKey, 'hex') }, + new PublicKey.Ed25519(publicKey), networkId ), (error: any): Error => error ) -const deriveVirtualEddsaEd25519AccountAddress = ( +export const deriveVirtualEddsaEd25519AccountAddress = ( publicKey: string, networkId: number ) => ResultAsync.fromPromise( RadixEngineToolkit.Derive.virtualAccountAddressFromPublicKey( - { kind: 'Ed25519', publicKey: Buffer.from(publicKey, 'hex') }, + new PublicKey.Ed25519(publicKey), networkId ), (error: any): Error => error ) -const deriveVirtualEcdsaSecp256k1AccountAddress = ( +export const deriveVirtualEcdsaSecp256k1AccountAddress = ( publicKey: string, networkId: number ) => ResultAsync.fromPromise( RadixEngineToolkit.Derive.virtualAccountAddressFromPublicKey( - { kind: 'Secp256k1', publicKey: Buffer.from(publicKey, 'hex') }, + new PublicKey.Secp256k1(publicKey), networkId ), (error: any): Error => error diff --git a/package-lock.json b/package-lock.json index 1a864aa7..cfe570cb 100644 --- a/package-lock.json +++ b/package-lock.json @@ -9,8 +9,8 @@ "version": "0.0.0", "license": "Apache-2.0", "dependencies": { - "@radixdlt/babylon-gateway-api-sdk": "^1.0.0-fig.6", - "@radixdlt/connect-button": "0.13.3", + "@radixdlt/babylon-gateway-api-sdk": "^1.0.0-grape.1", + "@radixdlt/connect-button": "0.13.4", "@radixdlt/wallet-sdk": "0.10.1-alpha.1", "immer": "^10.0.2", "lodash.isequal": "^4.5.0", @@ -30,7 +30,7 @@ "@mui/icons-material": "^5.11.16", "@mui/joy": "^5.0.0-alpha.76", "@mui/material": "^5.12.1", - "@radixdlt/radix-engine-toolkit": "^0.3.0-fig.1", + "@radixdlt/radix-engine-toolkit": "0.3.0-grape.1", "@types/elliptic": "^6.4.14", "@types/jest": "^29.4.0", "@types/lodash.isequal": "^4.5.6", @@ -3283,14 +3283,14 @@ } }, "node_modules/@radixdlt/babylon-gateway-api-sdk": { - "version": "1.0.0-fig.6", - "resolved": "https://registry.npmjs.org/@radixdlt/babylon-gateway-api-sdk/-/babylon-gateway-api-sdk-1.0.0-fig.6.tgz", - "integrity": "sha512-v4IvDvDPyuxF5dxfAN6CtC6bbjq5QiPpFoZffCnLQVRpPecOSyvpOa0ItL1xrsj+dGh74p8QuT+Givwdnzt33g==" + "version": "1.0.0-grape.1", + "resolved": "https://registry.npmjs.org/@radixdlt/babylon-gateway-api-sdk/-/babylon-gateway-api-sdk-1.0.0-grape.1.tgz", + "integrity": "sha512-EWyj9p/VpLeFl90YPJhWoaxQkdVdMnG4V9SOW3x8CNucLcW7jg/Ewf7tQ4NZEp4cNrDUNdBPeQJXxp64+IZJ8w==" }, "node_modules/@radixdlt/connect-button": { - "version": "0.13.3", - "resolved": "https://registry.npmjs.org/@radixdlt/connect-button/-/connect-button-0.13.3.tgz", - "integrity": "sha512-XUj47PBO81hW4gQ4ViNhJaoaOjGZcGEEMvVi+r0u8wPTpyeGRwd+lX8Kyp0nNpTLASaNdZadM6bO/18RNZ/yGg==", + "version": "0.13.4", + "resolved": "https://registry.npmjs.org/@radixdlt/connect-button/-/connect-button-0.13.4.tgz", + "integrity": "sha512-5jeiiFJLBnJzC3nimWY7sKzQgRgtHAb0rMRjxtBxdBusr/HjTIoedLmOHBv5Yc+kpJSKAdtBp/PovaVOcM06qQ==", "dependencies": { "lit": "^2.7.5" }, @@ -3299,9 +3299,9 @@ } }, "node_modules/@radixdlt/radix-engine-toolkit": { - "version": "0.3.0-pre-release.1", - "resolved": "https://registry.npmjs.org/@radixdlt/radix-engine-toolkit/-/radix-engine-toolkit-0.3.0-pre-release.1.tgz", - "integrity": "sha512-CG4EHrBbmOCwD/lgNCOt08i95qKgz0fn/Os6/B+vTeyojSJHMCOdo6CFuRIsANuzOzOaSajGlzMFYbthtcuHHQ==", + "version": "0.3.0-grape.1", + "resolved": "https://registry.npmjs.org/@radixdlt/radix-engine-toolkit/-/radix-engine-toolkit-0.3.0-grape.1.tgz", + "integrity": "sha512-X0JurkelF/Rtj7HbA0akDJgZY0aMghdFMTEFtVwY27ggq/jN+r5vsfs+8kjAqpsh9KHX0DRV1ydDJP9YJ7CoJg==", "dev": true, "dependencies": { "@noble/ed25519": "2.0.0", diff --git a/package.json b/package.json index f8e7d3d6..f8f058a6 100644 --- a/package.json +++ b/package.json @@ -48,8 +48,8 @@ "test:watch": "jest --watch" }, "dependencies": { - "@radixdlt/babylon-gateway-api-sdk": "^1.0.0-fig.6", - "@radixdlt/connect-button": "0.13.3", + "@radixdlt/babylon-gateway-api-sdk": "^1.0.0-grape.1", + "@radixdlt/connect-button": "0.13.4", "@radixdlt/wallet-sdk": "0.10.1-alpha.1", "immer": "^10.0.2", "lodash.isequal": "^4.5.0", @@ -69,7 +69,7 @@ "@mui/icons-material": "^5.11.16", "@mui/joy": "^5.0.0-alpha.76", "@mui/material": "^5.12.1", - "@radixdlt/radix-engine-toolkit": "^0.3.0-fig.1", + "@radixdlt/radix-engine-toolkit": "0.3.0-grape.1", "@types/elliptic": "^6.4.14", "@types/jest": "^29.4.0", "@types/lodash.isequal": "^4.5.6", diff --git a/release.config.js b/release.config.js index 7faa5b42..ec8b0be4 100644 --- a/release.config.js +++ b/release.config.js @@ -4,8 +4,8 @@ module.exports = { 'next', { name: 'develop', - channel: 'dev-fig', - prerelease: 'dev-fig', + channel: 'dev-grape', + prerelease: 'dev-grape', }, { name: 'release/([a-z0-9-]+)', diff --git a/src/_types.ts b/src/_types.ts index 838d75f3..a6248edd 100644 --- a/src/_types.ts +++ b/src/_types.ts @@ -100,14 +100,20 @@ export type SendTransactionResult = ResultAsync< transactionIntentHash: string status: TransactionStatus }, - { error: string; message?: string } + { + error: string + message?: string + transactionIntentHash?: string + status?: TransactionStatus + } > export type SendTransactionInput = { transactionManifest: string - version: number - blobs?: string[] | undefined - message?: string | undefined + version?: number + blobs?: string[] + message?: string + onTransactionId?: (transactionId: string) => void } export type GatewayApi = { diff --git a/src/data-request/data-request.ts b/src/data-request/data-request.ts index c3d65894..45760c3b 100644 --- a/src/data-request/data-request.ts +++ b/src/data-request/data-request.ts @@ -110,7 +110,6 @@ export const DataRequestClient = ({ const { id } = requestItemClient.add( isLoginRequest ? 'loginRequest' : 'dataRequest' ) - return walletClient .request(walletDataRequest, id) .mapErr( diff --git a/src/data-request/transformations/rdt-to-wallet.ts b/src/data-request/transformations/rdt-to-wallet.ts index 220aaf75..00bba39f 100644 --- a/src/data-request/transformations/rdt-to-wallet.ts +++ b/src/data-request/transformations/rdt-to-wallet.ts @@ -21,9 +21,9 @@ export const TransformRdtDataRequestToWalletRequestInput = object({ challenge: string().optional(), }).optional(), personaData: object({ - fullName: boolean().optional(), - phoneNumbers: NumberOfValues.optional(), - emailAddresses: NumberOfValues.optional(), + isRequestingName: boolean().optional(), + numberOfRequestedPhoneNumbers: NumberOfValues.optional(), + numberOfRequestedEmailAddresses: NumberOfValues.optional(), reset: boolean(), oneTime: boolean().optional(), }).optional(), @@ -114,9 +114,9 @@ const withPersonaDataRequestItem = if (input.personaData) { const { - fullName: isRequestingName, - phoneNumbers: numberOfRequestedPhoneNumbers, - emailAddresses: numberOfRequestedEmailAddresses, + isRequestingName, + numberOfRequestedPhoneNumbers, + numberOfRequestedEmailAddresses, } = input.personaData if (input.personaData?.oneTime) { diff --git a/src/gateway/gateway-api.ts b/src/gateway/gateway-api.ts index e429d03a..b1a0d284 100644 --- a/src/gateway/gateway-api.ts +++ b/src/gateway/gateway-api.ts @@ -14,15 +14,15 @@ export const GatewayApiClient = ({ basePath, }) - const getTransactionStatus = (transactionIntentHashHex: string) => + const getTransactionStatus = (transactionIntentHash: string) => ResultAsync.fromPromise( - transaction.getStatus(transactionIntentHashHex), + transaction.getStatus(transactionIntentHash), errorIdentity ) - const getTransactionDetails = (transactionIntentHashHex: string) => + const getTransactionDetails = (transactionIntentHash: string) => ResultAsync.fromPromise( - transaction.getCommittedDetails(transactionIntentHashHex), + transaction.getCommittedDetails(transactionIntentHash), errorIdentity ) diff --git a/src/gateway/gateway.ts b/src/gateway/gateway.ts index e6786631..8cf146d9 100644 --- a/src/gateway/gateway.ts +++ b/src/gateway/gateway.ts @@ -31,7 +31,7 @@ export const GatewayClient = ({ logger?: AppLogger retryConfig?: ExponentialBackoffInput }) => { - const pollTransactionStatus = (transactionIntentHashHex: string) => { + const pollTransactionStatus = (transactionIntentHash: string) => { const retry = ExponentialBackoff(retryConfig) const completedTransactionStatus = new Set([ @@ -49,7 +49,7 @@ export const GatewayClient = ({ logger?.debug(`pollingTxStatus retry #${result.value + 1}`) return gatewayApi - .getTransactionStatus(transactionIntentHashHex) + .getTransactionStatus(transactionIntentHash) .map((response) => { if (completedTransactionStatus.has(response.status)) return response diff --git a/src/gateway/helpers/exponential-backoff.ts b/src/gateway/helpers/exponential-backoff.ts index f2de5403..148a655b 100644 --- a/src/gateway/helpers/exponential-backoff.ts +++ b/src/gateway/helpers/exponential-backoff.ts @@ -11,9 +11,9 @@ export type ExponentialBackoffInput = { export type ExponentialBackoff = typeof ExponentialBackoff export const ExponentialBackoff = ({ maxDelayTime = 10_000, - multiplier = 3, + multiplier = 2, timeout, - interval = 1_000, + interval = 2_000, }: ExponentialBackoffInput = {}) => { const trigger = new Subject() let numberOfRetries = 0 diff --git a/src/wallet/wallet-client.ts b/src/wallet/wallet-client.ts index 18d7535e..336e3e87 100644 --- a/src/wallet/wallet-client.ts +++ b/src/wallet/wallet-client.ts @@ -15,6 +15,9 @@ import { import { Logger } from 'tslog' import { GatewayClient } from '../gateway/gateway' import { RequestItemClient } from '../request-items/request-item-client' +import { TransactionStatus } from '@radixdlt/babylon-gateway-api-sdk' +import { err, ok } from 'neverthrow' +import { SendTransactionInput } from '../_types' export type WalletClient = ReturnType export const WalletClient = (input: { @@ -91,38 +94,56 @@ export const WalletClient = (input: { const subscriptions = new Subscription() - const sendTransaction = ( - input: Parameters[0] - ) => { + const sendTransaction = ({ + onTransactionId, + ...rest + }: SendTransactionInput) => { const { id } = requestItemClient.add('sendTransaction') return walletSdk - .sendTransaction(input, cancelRequestControl(id)) + .sendTransaction({ version: 1, ...rest }, cancelRequestControl(id)) .mapErr((response) => { requestItemClient.updateStatus({ id, status: 'fail', error: response.error, }) - logger?.debug(`⬇️walletErrorResponse`, response) + logger?.debug(`⬇️ walletErrorResponse`, response) + return response + }) + .map((response) => { + logger?.debug(`⬇️ walletSuccessResponse`, response) return response }) - .andThen(({ transactionIntentHash }) => - gatewayClient + .andThen(({ transactionIntentHash }) => { + if (onTransactionId) onTransactionId(transactionIntentHash) + return gatewayClient .pollTransactionStatus(transactionIntentHash) .map((transactionStatusResponse) => ({ transactionIntentHash, status: transactionStatusResponse.status, })) - ) - .map((response) => { + }) + .andThen((response) => { + const failedTransactionStatus: TransactionStatus[] = [ + TransactionStatus.Rejected, + TransactionStatus.CommittedFailure, + ] + + const isFailedTransaction = failedTransactionStatus.includes( + response.status + ) + requestItemClient.updateStatus({ id, - status: 'success', + status: isFailedTransaction ? 'fail' : 'success', transactionIntentHash: response.transactionIntentHash, }) - logger?.debug(`⬇️walletSuccessResponse`, response) - return response + logger?.debug(`🔁 Gateway polling finished`, response) + + return isFailedTransaction + ? err({ ...response, error: 'transactionNotSuccessful' }) + : ok(response) }) }