1649915640
Synthetix is a crypto-backed synthetic asset platform.
It is a multi-token system, powered by SNX, the Synthetix Network Token. SNX holders can stake SNX to issue Synths, on-chain synthetic assets via the Staking dApp The network currently supports an ever growing list of synthetic assets. Please see the list of the deployed contracts on MAIN and TESTNETS Synths can be traded using Kwenta
Synthetix uses a proxy system so that upgrades will not be disruptive to the functionality of the contract. This smooths user interaction, since new functionality will become available without any interruption in their experience. It is also transparent to the community at large, since each upgrade is accompanied by events announcing those upgrades. New releases are managed via the Synthetix Improvement Proposal (SIP) system similar to the EIPs
Prices are committed on chain by a trusted oracle provided by Chainlink.
Please note that this repository is under development.
For the latest system documentation see docs.synthetix.io
A note on the branches used in this repo.
master
represents the contracts live on mainnet
and all testnets.When a new version of the contracts makes its way through all testnets, it eventually becomes promoted in master
, with semver reflecting contract changes in the major
or minor
portion of the version (depending on backwards compatibility). patch
changes are simply for changes to the JavaScript interface.
This repo may be installed via npm install
to support both node.js scripting applications and Solidity contract development.
:100: Please see our walkthroughs for code examples in both JavaScript and Solidity: docs.synthetix.io/integrations
All interfaces are available via the path synthetix/contracts/interfaces
.
:zap: In your code, the key is to use IAddressResolver
which can be tied to the immutable proxy: ReadProxyAddressResolver
(introduced in SIP-57). You can then fetch Synthetix
, FeePool
, Depot
, et al via IAddressResolver.getAddress(bytes32 name)
where name
is the bytes32
version of the contract name (case-sensitive). Or you can fetch any synth using IAddressResolver.getSynth(bytes32 synth)
where synth
is the bytes32
name of the synth (e.g. iETH
, sUSD
, sDEFI
).
E.g.
npm install synthetix
then you can write Solidity as below (using a compiler that links named imports via node_modules
):
pragma solidity 0.5.16;
import 'synthetix/contracts/interfaces/IAddressResolver.sol';
import 'synthetix/contracts/interfaces/ISynthetix.sol';
contract MyContract {
// This should be instantiated with our ReadProxyAddressResolver
// it's a ReadProxy that won't change, so safe to code it here without a setter
// see https://docs.synthetix.io/addresses for addresses in mainnet and testnets
IAddressResolver public synthetixResolver;
constructor(IAddressResolver _snxResolver) public {
synthetixResolver = _snxResolver;
}
function synthetixIssue() external {
ISynthetix synthetix = synthetixResolver.getAddress('Synthetix');
require(synthetix != address(0), 'Synthetix is missing from Synthetix resolver');
// Issue for msg.sender = address(MyContract)
synthetix.issueMaxSynths();
}
function synthetixIssueOnBehalf(address user) external {
ISynthetix synthetix = synthetixResolver.getAddress('Synthetix');
require(synthetix != address(0), 'Synthetix is missing from Synthetix resolver');
// Note: this will fail if `DelegateApprovals.approveIssueOnBehalf(address(MyContract))` has
// not yet been invoked by the `user`
synthetix.issueMaxSynthsOnBehalf(user);
}
}
getAST({ source, match = /^contracts\// })
Returns the Abstract Syntax Tree (AST) for all compiled sources. Optionally add source
to restrict to a single contract source, and set match
to an empty regex if you'd like all source ASTs including third party contractsgetPathToNetwork({ network, file = '' })
Returns the path to the folder (or file within the folder) for the given networkgetSource({ network })
Return abi
and bytecode
for a contract source
getSuspensionReasons({ code })
Return mapping of SystemStatus
suspension codes to string reasonsgetStakingRewards({ network })
Return the list of staking reward contracts available.getSynths({ network })
Return the list of synths for a networkgetTarget({ network })
Return the information about a contract's address
and source
file. The contract names are those specified in docs.synthetix.io/addressesgetTokens({ network })
Return the list of tokens (synths and SNX
) used in the system, along with their addresses.getUsers({ network })
Return the list of user accounts within the Synthetix protocol (e.g. owner
, fee
, etc)getVersions({ network, byContract = false })
Return the list of deployed versions to the network keyed by tagged version. If byContract
is true
, it keys by contract
name.networks
Return the list of supported networkstoBytes32
Convert any string to a bytes32
valueconst snx = require('synthetix');
snx.getAST();
/*
{ 'contracts/AddressResolver.sol':
{ imports:
[ 'contracts/Owned.sol',
'contracts/interfaces/IAddressResolver.sol',
'contracts/interfaces/ISynthetix.sol' ],
contracts: { AddressResolver: [Object] },
interfaces: {},
libraries: {} },
'contracts/Owned.sol':
{ imports: [],
contracts: { Owned: [Object] },
interfaces: {},
libraries: {} },
*/
snx.getAST({ source: 'Synthetix.sol' });
/*
{ imports:
[ 'contracts/ExternStateToken.sol',
'contracts/MixinResolver.sol',
'contracts/interfaces/ISynthetix.sol',
'contracts/TokenState.sol',
'contracts/interfaces/ISynth.sol',
'contracts/interfaces/IERC20.sol',
'contracts/interfaces/ISystemStatus.sol',
'contracts/interfaces/IExchanger.sol',
'contracts/interfaces/IIssuer.sol',
'contracts/interfaces/ISynthetixState.sol',
'contracts/interfaces/IExchangeRates.sol',
'contracts/SupplySchedule.sol',
'contracts/interfaces/IRewardEscrow.sol',
'contracts/interfaces/IHasBalance.sol',
'contracts/interfaces/IRewardsDistribution.sol' ],
contracts:
{ Synthetix:
{ functions: [Array],
events: [Array],
variables: [Array],
modifiers: [Array],
structs: [],
inherits: [Array] } },
interfaces: {},
libraries: {} }
*/
// Get the path to the network
snx.getPathToNetwork({ network: 'mainnet' });
//'.../Synthetixio/synthetix/publish/deployed/mainnet'
// retrieve an object detailing the contract ABI and bytecode
snx.getSource({ network: 'rinkeby', contract: 'Proxy' });
/*
{
bytecode: '0..0',
abi: [ ... ]
}
*/
snx.getSuspensionReasons();
/*
{
1: 'System Upgrade',
2: 'Market Closure',
3: 'Circuit breaker',
99: 'Emergency',
};
*/
// retrieve the array of synths used
snx.getSynths({ network: 'rinkeby' }).map(({ name }) => name);
// ['sUSD', 'sEUR', ...]
// retrieve an object detailing the contract deployed to the given network.
snx.getTarget({ network: 'rinkeby', contract: 'ProxySynthetix' });
/*
{
name: 'ProxySynthetix',
address: '0x322A3346bf24363f451164d96A5b5cd5A7F4c337',
source: 'Proxy',
link: 'https://rinkeby.etherscan.io/address/0x322A3346bf24363f451164d96A5b5cd5A7F4c337',
timestamp: '2019-03-06T23:05:43.914Z',
txn: '',
network: 'rinkeby'
}
*/
// retrieve the list of system user addresses
snx.getUsers({ network: 'mainnet' });
/*
[ { name: 'owner',
address: '0xEb3107117FEAd7de89Cd14D463D340A2E6917769' },
{ name: 'deployer',
address: '0xDe910777C787903F78C89e7a0bf7F4C435cBB1Fe' },
{ name: 'marketClosure',
address: '0xC105Ea57Eb434Fbe44690d7Dec2702e4a2FBFCf7' },
{ name: 'oracle',
address: '0xaC1ED4Fabbd5204E02950D68b6FC8c446AC95362' },
{ name: 'fee',
address: '0xfeEFEEfeefEeFeefEEFEEfEeFeefEEFeeFEEFEeF' },
{ name: 'zero',
address: '0x0000000000000000000000000000000000000000' } ]
*/
snx.getVersions();
/*
{ 'v2.21.12-107':
{ tag: 'v2.21.12-107',
fulltag: 'v2.21.12-107',
release: 'Hadar',
network: 'kovan',
date: '2020-05-08T12:52:06-04:00',
commit: '19997724bc7eaceb902c523a6742e0bd74fc75cb',
contracts: { ReadProxyAddressResolver: [Object] }
}
}
*/
snx.networks;
// [ 'local', 'kovan', 'rinkeby', 'ropsten', 'mainnet' ]
snx.toBytes32('sUSD');
// '0x7355534400000000000000000000000000000000000000000000000000000000'
Same as above but as a CLI tool that outputs JSON, using names without the get
prefixes:
$ npx synthetix ast contracts/Synth.sol
{
"imports": [
"contracts/Owned.sol",
"contracts/ExternStateToken.sol",
"contracts/MixinResolver.sol",
"contracts/interfaces/ISynth.sol",
"contracts/interfaces/IERC20.sol",
"contracts/interfaces/ISystemStatus.sol",
"contracts/interfaces/IFeePool.sol",
"contracts/interfaces/ISynthetix.sol",
"contracts/interfaces/IExchanger.sol",
"contracts/interfaces/IIssue"
# ...
]
}
$ npx synthetix bytes32 sUSD
0x7355534400000000000000000000000000000000000000000000000000000000
$ npx synthetix networks
[ 'local', 'kovan', 'rinkeby', 'ropsten', 'mainnet' ]
$ npx synthetix source --network rinkeby --contract Proxy
{
"bytecode": "0..0",
"abi": [ ... ]
}
$ npx synthetix suspension-reason --code 2
Market Closure
$ npx synthetix synths --network rinkeby --key name
["sUSD", "sEUR", ... ]
$ npx synthetix target --network rinkeby --contract ProxySynthetix
{
"name": "ProxySynthetix",
"address": "0x322A3346bf24363f451164d96A5b5cd5A7F4c337",
"source": "Proxy",
"link": "https://rinkeby.etherscan.io/address/0x322A3346bf24363f451164d96A5b5cd5A7F4c337",
"timestamp": "2019-03-06T23:05:43.914Z",
"network": "rinkeby"
}
$ npx synthetix users --network mainnet --user oracle
{
"name": "oracle",
"address": "0xaC1ED4Fabbd5204E02950D68b6FC8c446AC95362"
}
$ npx synthetix versions
{
"v2.0-19": {
"tag": "v2.0-19",
"fulltag": "v2.0-19",
"release": "",
"network": "mainnet",
"date": "2019-03-11T18:17:52-04:00",
"commit": "eeb271f4fdd2e615f9dba90503f42b2cb9f9716e",
"contracts": {
"Depot": {
"address": "0x172E09691DfBbC035E37c73B62095caa16Ee2388",
"status": "replaced",
"replaced_in": "v2.18.1"
},
"ExchangeRates": {
"address": "0x73b172756BD5DDf0110Ba8D7b88816Eb639Eb21c",
"status": "replaced",
"replaced_in": "v2.1.11"
},
# ...
}
}
}
$ npx synthetix versions --by-contract
{
"Depot": [
{
"address": "0x172E09691DfBbC035E37c73B62095caa16Ee2388",
"status": "replaced",
"replaced_in": "v2.18.1"
},
{
"address": "0xE1f64079aDa6Ef07b03982Ca34f1dD7152AA3b86",
"status": "current"
}
],
"ExchangeRates": [
{
"address": "0x73b172756BD5DDf0110Ba8D7b88816Eb639Eb21c",
"status": "replaced",
"replaced_in": "v2.1.11"
},
# ...
],
# ...
}
Download Details:
Author: Synthetixio
Source Code: https://github.com/Synthetixio/synthetix
License: MIT License
#blockchain #smartcontract #ethereum #solidity
1648115675
Germany was the first country to recognize #Bitcoins as “units of value” and that they could be classified as a “financial instrument.”
Legal regulation for the decentralized industry in Germany is ongoing. Now, 16% of the German population 18 to 60 are #crypto investors.
These people who own #cryptocurrencies or have traded cryptocurrencies in the past six months.
41% of these #crypto investors intend to increase the share of their investments in #crypto in the next six months. Another 13% of Germans are #crypto-curious.
They intend to invest in #cryptocurrencies too. Yet, only 23% of the #crypto-curious said they are highly likely to invest, with the rest remaining hesitant.
1649915640
Synthetix is a crypto-backed synthetic asset platform.
It is a multi-token system, powered by SNX, the Synthetix Network Token. SNX holders can stake SNX to issue Synths, on-chain synthetic assets via the Staking dApp The network currently supports an ever growing list of synthetic assets. Please see the list of the deployed contracts on MAIN and TESTNETS Synths can be traded using Kwenta
Synthetix uses a proxy system so that upgrades will not be disruptive to the functionality of the contract. This smooths user interaction, since new functionality will become available without any interruption in their experience. It is also transparent to the community at large, since each upgrade is accompanied by events announcing those upgrades. New releases are managed via the Synthetix Improvement Proposal (SIP) system similar to the EIPs
Prices are committed on chain by a trusted oracle provided by Chainlink.
Please note that this repository is under development.
For the latest system documentation see docs.synthetix.io
A note on the branches used in this repo.
master
represents the contracts live on mainnet
and all testnets.When a new version of the contracts makes its way through all testnets, it eventually becomes promoted in master
, with semver reflecting contract changes in the major
or minor
portion of the version (depending on backwards compatibility). patch
changes are simply for changes to the JavaScript interface.
This repo may be installed via npm install
to support both node.js scripting applications and Solidity contract development.
:100: Please see our walkthroughs for code examples in both JavaScript and Solidity: docs.synthetix.io/integrations
All interfaces are available via the path synthetix/contracts/interfaces
.
:zap: In your code, the key is to use IAddressResolver
which can be tied to the immutable proxy: ReadProxyAddressResolver
(introduced in SIP-57). You can then fetch Synthetix
, FeePool
, Depot
, et al via IAddressResolver.getAddress(bytes32 name)
where name
is the bytes32
version of the contract name (case-sensitive). Or you can fetch any synth using IAddressResolver.getSynth(bytes32 synth)
where synth
is the bytes32
name of the synth (e.g. iETH
, sUSD
, sDEFI
).
E.g.
npm install synthetix
then you can write Solidity as below (using a compiler that links named imports via node_modules
):
pragma solidity 0.5.16;
import 'synthetix/contracts/interfaces/IAddressResolver.sol';
import 'synthetix/contracts/interfaces/ISynthetix.sol';
contract MyContract {
// This should be instantiated with our ReadProxyAddressResolver
// it's a ReadProxy that won't change, so safe to code it here without a setter
// see https://docs.synthetix.io/addresses for addresses in mainnet and testnets
IAddressResolver public synthetixResolver;
constructor(IAddressResolver _snxResolver) public {
synthetixResolver = _snxResolver;
}
function synthetixIssue() external {
ISynthetix synthetix = synthetixResolver.getAddress('Synthetix');
require(synthetix != address(0), 'Synthetix is missing from Synthetix resolver');
// Issue for msg.sender = address(MyContract)
synthetix.issueMaxSynths();
}
function synthetixIssueOnBehalf(address user) external {
ISynthetix synthetix = synthetixResolver.getAddress('Synthetix');
require(synthetix != address(0), 'Synthetix is missing from Synthetix resolver');
// Note: this will fail if `DelegateApprovals.approveIssueOnBehalf(address(MyContract))` has
// not yet been invoked by the `user`
synthetix.issueMaxSynthsOnBehalf(user);
}
}
getAST({ source, match = /^contracts\// })
Returns the Abstract Syntax Tree (AST) for all compiled sources. Optionally add source
to restrict to a single contract source, and set match
to an empty regex if you'd like all source ASTs including third party contractsgetPathToNetwork({ network, file = '' })
Returns the path to the folder (or file within the folder) for the given networkgetSource({ network })
Return abi
and bytecode
for a contract source
getSuspensionReasons({ code })
Return mapping of SystemStatus
suspension codes to string reasonsgetStakingRewards({ network })
Return the list of staking reward contracts available.getSynths({ network })
Return the list of synths for a networkgetTarget({ network })
Return the information about a contract's address
and source
file. The contract names are those specified in docs.synthetix.io/addressesgetTokens({ network })
Return the list of tokens (synths and SNX
) used in the system, along with their addresses.getUsers({ network })
Return the list of user accounts within the Synthetix protocol (e.g. owner
, fee
, etc)getVersions({ network, byContract = false })
Return the list of deployed versions to the network keyed by tagged version. If byContract
is true
, it keys by contract
name.networks
Return the list of supported networkstoBytes32
Convert any string to a bytes32
valueconst snx = require('synthetix');
snx.getAST();
/*
{ 'contracts/AddressResolver.sol':
{ imports:
[ 'contracts/Owned.sol',
'contracts/interfaces/IAddressResolver.sol',
'contracts/interfaces/ISynthetix.sol' ],
contracts: { AddressResolver: [Object] },
interfaces: {},
libraries: {} },
'contracts/Owned.sol':
{ imports: [],
contracts: { Owned: [Object] },
interfaces: {},
libraries: {} },
*/
snx.getAST({ source: 'Synthetix.sol' });
/*
{ imports:
[ 'contracts/ExternStateToken.sol',
'contracts/MixinResolver.sol',
'contracts/interfaces/ISynthetix.sol',
'contracts/TokenState.sol',
'contracts/interfaces/ISynth.sol',
'contracts/interfaces/IERC20.sol',
'contracts/interfaces/ISystemStatus.sol',
'contracts/interfaces/IExchanger.sol',
'contracts/interfaces/IIssuer.sol',
'contracts/interfaces/ISynthetixState.sol',
'contracts/interfaces/IExchangeRates.sol',
'contracts/SupplySchedule.sol',
'contracts/interfaces/IRewardEscrow.sol',
'contracts/interfaces/IHasBalance.sol',
'contracts/interfaces/IRewardsDistribution.sol' ],
contracts:
{ Synthetix:
{ functions: [Array],
events: [Array],
variables: [Array],
modifiers: [Array],
structs: [],
inherits: [Array] } },
interfaces: {},
libraries: {} }
*/
// Get the path to the network
snx.getPathToNetwork({ network: 'mainnet' });
//'.../Synthetixio/synthetix/publish/deployed/mainnet'
// retrieve an object detailing the contract ABI and bytecode
snx.getSource({ network: 'rinkeby', contract: 'Proxy' });
/*
{
bytecode: '0..0',
abi: [ ... ]
}
*/
snx.getSuspensionReasons();
/*
{
1: 'System Upgrade',
2: 'Market Closure',
3: 'Circuit breaker',
99: 'Emergency',
};
*/
// retrieve the array of synths used
snx.getSynths({ network: 'rinkeby' }).map(({ name }) => name);
// ['sUSD', 'sEUR', ...]
// retrieve an object detailing the contract deployed to the given network.
snx.getTarget({ network: 'rinkeby', contract: 'ProxySynthetix' });
/*
{
name: 'ProxySynthetix',
address: '0x322A3346bf24363f451164d96A5b5cd5A7F4c337',
source: 'Proxy',
link: 'https://rinkeby.etherscan.io/address/0x322A3346bf24363f451164d96A5b5cd5A7F4c337',
timestamp: '2019-03-06T23:05:43.914Z',
txn: '',
network: 'rinkeby'
}
*/
// retrieve the list of system user addresses
snx.getUsers({ network: 'mainnet' });
/*
[ { name: 'owner',
address: '0xEb3107117FEAd7de89Cd14D463D340A2E6917769' },
{ name: 'deployer',
address: '0xDe910777C787903F78C89e7a0bf7F4C435cBB1Fe' },
{ name: 'marketClosure',
address: '0xC105Ea57Eb434Fbe44690d7Dec2702e4a2FBFCf7' },
{ name: 'oracle',
address: '0xaC1ED4Fabbd5204E02950D68b6FC8c446AC95362' },
{ name: 'fee',
address: '0xfeEFEEfeefEeFeefEEFEEfEeFeefEEFeeFEEFEeF' },
{ name: 'zero',
address: '0x0000000000000000000000000000000000000000' } ]
*/
snx.getVersions();
/*
{ 'v2.21.12-107':
{ tag: 'v2.21.12-107',
fulltag: 'v2.21.12-107',
release: 'Hadar',
network: 'kovan',
date: '2020-05-08T12:52:06-04:00',
commit: '19997724bc7eaceb902c523a6742e0bd74fc75cb',
contracts: { ReadProxyAddressResolver: [Object] }
}
}
*/
snx.networks;
// [ 'local', 'kovan', 'rinkeby', 'ropsten', 'mainnet' ]
snx.toBytes32('sUSD');
// '0x7355534400000000000000000000000000000000000000000000000000000000'
Same as above but as a CLI tool that outputs JSON, using names without the get
prefixes:
$ npx synthetix ast contracts/Synth.sol
{
"imports": [
"contracts/Owned.sol",
"contracts/ExternStateToken.sol",
"contracts/MixinResolver.sol",
"contracts/interfaces/ISynth.sol",
"contracts/interfaces/IERC20.sol",
"contracts/interfaces/ISystemStatus.sol",
"contracts/interfaces/IFeePool.sol",
"contracts/interfaces/ISynthetix.sol",
"contracts/interfaces/IExchanger.sol",
"contracts/interfaces/IIssue"
# ...
]
}
$ npx synthetix bytes32 sUSD
0x7355534400000000000000000000000000000000000000000000000000000000
$ npx synthetix networks
[ 'local', 'kovan', 'rinkeby', 'ropsten', 'mainnet' ]
$ npx synthetix source --network rinkeby --contract Proxy
{
"bytecode": "0..0",
"abi": [ ... ]
}
$ npx synthetix suspension-reason --code 2
Market Closure
$ npx synthetix synths --network rinkeby --key name
["sUSD", "sEUR", ... ]
$ npx synthetix target --network rinkeby --contract ProxySynthetix
{
"name": "ProxySynthetix",
"address": "0x322A3346bf24363f451164d96A5b5cd5A7F4c337",
"source": "Proxy",
"link": "https://rinkeby.etherscan.io/address/0x322A3346bf24363f451164d96A5b5cd5A7F4c337",
"timestamp": "2019-03-06T23:05:43.914Z",
"network": "rinkeby"
}
$ npx synthetix users --network mainnet --user oracle
{
"name": "oracle",
"address": "0xaC1ED4Fabbd5204E02950D68b6FC8c446AC95362"
}
$ npx synthetix versions
{
"v2.0-19": {
"tag": "v2.0-19",
"fulltag": "v2.0-19",
"release": "",
"network": "mainnet",
"date": "2019-03-11T18:17:52-04:00",
"commit": "eeb271f4fdd2e615f9dba90503f42b2cb9f9716e",
"contracts": {
"Depot": {
"address": "0x172E09691DfBbC035E37c73B62095caa16Ee2388",
"status": "replaced",
"replaced_in": "v2.18.1"
},
"ExchangeRates": {
"address": "0x73b172756BD5DDf0110Ba8D7b88816Eb639Eb21c",
"status": "replaced",
"replaced_in": "v2.1.11"
},
# ...
}
}
}
$ npx synthetix versions --by-contract
{
"Depot": [
{
"address": "0x172E09691DfBbC035E37c73B62095caa16Ee2388",
"status": "replaced",
"replaced_in": "v2.18.1"
},
{
"address": "0xE1f64079aDa6Ef07b03982Ca34f1dD7152AA3b86",
"status": "current"
}
],
"ExchangeRates": [
{
"address": "0x73b172756BD5DDf0110Ba8D7b88816Eb639Eb21c",
"status": "replaced",
"replaced_in": "v2.1.11"
},
# ...
],
# ...
}
Download Details:
Author: Synthetixio
Source Code: https://github.com/Synthetixio/synthetix
License: MIT License
1616494541
Overtake your competitors with unique ideas in the digital marketplace with Blockchain App Factory that offers P2P Lending Software. It contains all the latest features with an efficient engine, stable agreement order and market order, central management system, real-time traceable machine, and much more.
#p2p lending blockchain #p2p lending blockchain platform #p2p lending platforms #peer to peer lending blockchain platform #blockchain-based p2p lending platforms #p2p crypto lending software
1615454471
Our Whitelabel crypto exchange platform is equipped with trending features like access to full transaction history for the user anytime, multi-currency deposits and withdrawals by QR code and email, availability of multiple trading pairs, provision of real-time notifications, two-factor authentication, 256SHA encryption, availability of hot and cold multisignature wallets, and firewall implementation.
The benefits include the creation of more trust among investors, transparent pricing, extreme scalability, rapid deployment, high performance, complete customization, and supreme security measures.
The additional aspects we offer are an unlimited supply of ERC-20 tokens, integration with numerous payment gateways, a launchpad for IEO, email interfacing, merchant plugin facility, margin trading option, and direct P2P transfers between users.
#white label crypto exchange #crypto exchange platform #crypto exchange #exchange platform
1623323207
Cross-Platform Development Services
With the development in mobile app technology, a huge time saver as well as the quality maintainer technology is Cross-Platform App development. The development of an app that takes less time to develop as well as uses one technology to develop an app for both android and iOS is game-changing technology in mobile app development.
Want to develop or design a Cross-platform app?
With the successful delivery of more than 950 projects, WebClues Infotech has got the expertise as well as a huge experience of cross-platform app development and design. With global offices in 4 continents and a customer presence in most developed countries, WebClues Infotech has got a huge network around the world.
Want to know more about our cross-platform app designs?
Visit: https://www.webcluesinfotech.com/cross-platform-design/
Share your requirements https://www.webcluesinfotech.com/contact-us/
View Portfolio https://www.webcluesinfotech.com/portfolio/
#cross-platform development services #cross platform mobile app development services #cross-platform mobile app development services #cross platform app development services #hire cross platform app developer #hire cross-platform app developer india usa,