diff --git a/packages/client-browser/README.md b/packages/client-browser/README.md index 585a8342..f51fc054 100644 --- a/packages/client-browser/README.md +++ b/packages/client-browser/README.md @@ -8,4 +8,4 @@ Use your favorite package manager (e.g. yarn) and install package `@logion/clien ## Usage -See [core client](../client/README.md). +See [documentation](https://logion-network.github.io/logion-api/). diff --git a/packages/client-expo/README.md b/packages/client-expo/README.md index fae4bc10..23cd2e98 100644 --- a/packages/client-expo/README.md +++ b/packages/client-expo/README.md @@ -16,32 +16,4 @@ global.Buffer = Buffer; ## Usage -Instantiate the Logion client using `newLogionClient` function. For example, to connect to our test environment use: - -```typescript -import { Environment } from "@logion/client"; -import { newLogionClient } from '@logion/client-expo'; - -const client = await newLogionClient(Environment.TEST); -``` - -See [here](../client/README.md) for instructions about how to use the client. - -Each time you need to pass a file to the client (e.g. when creating a collection item or a tokens record), -pass an instance of `ExpoFile`. The constructor expects 3 arguments: - -- the [URI](https://docs.expo.dev/versions/latest/sdk/filesystem/#api) of the file, -- its name (e.g. `my-document.pdf`), -- its MIME type (e.g. `application/pdf`). - -Here is an example: - -```typescript -// ... -import { MimeType } from "@logion/client"; -import { ExpoFile } from '@logion/client-expo'; -// ... - -const fileName = "file.txt"; -const file = new ExpoFile(`${FileSystem.cacheDirectory}/${fileName}`, fileName, MimeType.from("text/plain")); -``` +See [documentation](https://logion-network.github.io/logion-api/). diff --git a/packages/client-node/README.md b/packages/client-node/README.md index 90f95c01..295345dc 100644 --- a/packages/client-node/README.md +++ b/packages/client-node/README.md @@ -8,7 +8,7 @@ Use your favorite package manager (e.g. yarn) and install package `@logion/clien ## Usage -See [core client](../client/README.md). +See [documentation](https://logion-network.github.io/logion-api/). ## Integration tests diff --git a/packages/client-react-native-fs/README.md b/packages/client-react-native-fs/README.md index 586caad5..aa6a3a08 100644 --- a/packages/client-react-native-fs/README.md +++ b/packages/client-react-native-fs/README.md @@ -10,10 +10,4 @@ Use your favorite package manager (e.g. yarn) and install package `@logion/clien ## Usage -This module provides `ReactNativeFsFile` and `ReactNativeFileUploader` classes. - -An instance of `ReactNativeFileUploader` (use the zero-argument constructor) must be provided to `LogionClient.create(...)`. - -`ReactNativeFsFile` instances (the constructor takes takes a single string argument, the path) must be passed to SDK whenever needed. - -See [core client](../client/README.md). +See [documentation](https://logion-network.github.io/logion-api/). diff --git a/packages/client/README.md b/packages/client/README.md index 15bc550a..8bb13789 100644 --- a/packages/client/README.md +++ b/packages/client/README.md @@ -8,258 +8,4 @@ Use your favorite package manager (e.g. yarn) and install package `@logion/clien ## Usage -### Authentication - -```typescript -import { LogionClient, KeyringSigner } from '@logion/client'; -import { Keyring } from '@polkadot/api'; - -const keyring = new Keyring(); -keyring.addFromUri("0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a"); // Alice -const signer = new KeyringSigner(keyring); - -const client = await LogionClient.create({ - rpcEndpoints: [ 'wss://rpc01.logion.network' ], // A list of websocket endpoints - directoryEndpoint: 'https://directory.logion.network', // A logion directory - buildFileUploader: ..., // A zero-argument function returning an instance of file uploader -}); - -// Authenticate Alice -const authenticatedClient = await client.authenticate([ "5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY" ], signer); - -// Use authenticatedClient to interact with the network -``` - -### Balance and Transactions - -```typescript -// Balance -let balanceState = await authenticatedClient.balanceState(); -const balance = balanceState.balances[0]; -console.log("Balance :%s", `${balance.balance.coefficient.toInteger()}.${balance.balance.coefficient.toFixedPrecisionDecimals(2)}${balance.balance.prefix.symbol}`) - -// Transactions -const transactions = balanceState.transactions; -console.log("First transaction destination: %s", transactions[0].destination) - -// Transfer -balanceState = balanceState.transfer({ - signer, - amount: new PrefixedNumber("2", KILO), - destination: ALICE.address -}); -``` - -### Protection - -```typescript -// Choose legal officers -const legalOfficers: LegalOfficer[] = authenticatedClient.getLegalOfficers(); - -const alice = legalOfficers[0]; -const bob = legalOfficers[1]; - -// Request a protection -const noProtection = await authenticatedClient.protectionState() as NoProtection; -const pending = await noProtection.requestProtection({ - legalOfficer1: alice, - legalOfficer2: bob, - userIdentity: { - email: "john.doe@invalid.domain", - firstName: "John", - lastName: "Doe", - phoneNumber: "+1234", - }, - postalAddress: { - city: "", - country: "", - line1: "", - line2: "", - postalCode: "", - } -}); - -// ... Wait for LO's acceptance ... -const accepted = (await pending.refresh()) as AcceptedProtection; - -// Activate the protection -accepted.activate(signer); -``` - -### Vault -Operations require an activated protection (see above "Protection") -```typescript -let activeProtection = (await authenticatedClient.protectionState()) as ActiveProtection; - -// Transfer from vault -let vaultState = await activeProtection.vaultState(); -const vaultAddress = vaultState.vaultAddress; -vaultState = await vaultState.createVaultTransferRequest({ - legalOfficer: alice, - amount: new PrefixedNumber("1", NONE), - destination: REQUESTER_ADDRESS, - signer -}); -const pendingRequest = vaultState.pendingVaultTransferRequests[0]; - -// ... Wait for LO's acceptance ... -vaultState = await vaultState.refresh(); - -// Check Vault balance -const balance = vaultState.balances[0]; -console.log("Balance :%s", `${balance.balance.coefficient.toInteger()}.${balance.balance.coefficient.toFixedPrecisionDecimals(2)}${balance.balance.prefix.symbol}`) -``` - -### Recovery - -```typescript -const NEW_ADDRESS = "5GsxAu1XexDATCbDJbWxKSow4gdC6epkajZr7Ht8Ci9VZabV"; - -const authenticatedClient = await LogionClient.create({ - rpcEndpoints: [ 'wss://rpc01.logion.network' ], // A list of websocket endpoints - directoryEndpoint: 'https://directory.logion.network' // A logion directory -}).authenticate([ NEW_ADDRESS ], signer); - -// Request a recovery -const noProtection = await authenticatedClient.protectionState() as NoProtection; -const pending = await noProtection.requestRecovery({ - recoveredAddress: REQUESTER_ADDRESS, - signer, - legalOfficer1: alice, - legalOfficer2: bob, - userIdentity: { - email: "john.doe@invalid.domain", - firstName: "John", - lastName: "Doe", - phoneNumber: "+1234", - }, - postalAddress: { - city: "", - country: "", - line1: "", - line2: "", - postalCode: "", - } -}); - -// ... Wait for LO's acceptance and vouching ... -const accepted = (await pending.refresh()) as AcceptedProtection; - -// Activate the new protection -let pendingRecovery = await accepted.activate(signer) as PendingRecovery; -pendingRecovery = await pendingRecovery.waitForFullyReady(); - -// Claim -const claimed = await pendingRecovery.claimRecovery(signer); - -// Recover the lost balance -const recoveredBalance = await claimed.recoveredBalanceState(); -await recoveredBalance.transfer({ - signer, - destination: NEW_ADDRESS, - amount: recoveredBalance.balances[0].available, -}); - -// Recover the lost vault -const newVault = await claimed.vaultState(); -let recoveredVault = await claimed.recoveredVaultState(); -recoveredVault = await recoveredVault.createVaultTransferRequest({ - legalOfficer: alice, - amount: recoveredVault.balances[0].available, - destination: newVault.vaultAddress, - signer, -}); - -// ... Wait for LO's acceptance ... -newVault = await newVault.refresh(); - -// Check Vault balance -const newBalance = newVault.balances[0]; -console.log("Balance :%s", `${newBalance.balance.coefficient.toInteger()}.${newBalance.balance.coefficient.toFixedPrecisionDecimals(2)}${newBalance.balance.prefix.symbol}`); -``` - -### Transaction Legal Officer Case (LOC) - -```typescript -let locsState = await authenticatedClient.locsState(); - -// Request a Transaction LOC -const pendingRequest = await locsState.requestTransactionLoc({ - legalOfficer: alice, - description: "This is a Transaction LOC", - // Below field is required only if the legal officer you are sending the request to - // does not already protect you (see Protection or Recovery). - userIdentity: { - email: "john.doe@invalid.domain", - firstName: "John", - lastName: "Doe", - phoneNumber: "+1234", - }, -}); - -// ... Wait for LO's acceptance ... -let openLoc = await pendingRequest.refresh() as OpenLoc; - -// Submit new elements to the LO through the LOC -openLoc = await openLoc.addMetadata({ - name: "Some name", - value: "Some value" -}); -const file: File = ...; // Platform dependent, see plugins -openLoc = await openLoc.addFile({ - fileName: "id.jpeg", - nature: "ID", - file, -}); - -// ... Wait for the LO to publish elements and close the LOC ... -const closedLoc = await openLoc.refresh() as ClosedLoc; -``` - -### Collection LOC and items - -```typescript -let locsState = await authenticatedClient.locsState(); - -// Request a collection LOC -const pendingRequest = await locsState.requestCollectionLoc({ - legalOfficer: alice, - description: "This is a Collection LOC", - userIdentity: { - email: "john.doe@invalid.domain", - firstName: "John", - lastName: "Doe", - phoneNumber: "+1234", - }, -}); - -// ... Wait for the LO to open the LOC with upload support, fill-it in then close it ... - -let closedLoc = await openLoc.refresh() as ClosedCollectionLoc; - -// Add an item to the collection LOC -const itemId = Hash.of("first-collection-item"); // Hash is provided by @logion/node-api -const itemDescription = "First collection item"; -const file: File = ...; // Platform dependent, see plugins -closedLoc = await closedLoc.addCollectionItem({ - itemId, - itemDescription, - signer, - itemFiles: [ // Must remain undefined with Collection LOCs without upload support - new ItemFileWithContent({ - name: "test.txt", - contentType: MimeType.from("text/plain"), - hashOrContent: HashOrContent.fromContent(file), // Let SDK compute hash and size - }) - ] -}); - -// Later, retrieve the item given its ID -const item = await closedLoc.getCollectionItem({ itemId }); -``` - -## Publication -In order to publish to [npm](https://www.npmjs.com/org/logion), you can use the following scripts: - -* `yarn check-publish` - to check the published package content. -* `yarn do-publish` - to actually publish (require authentication with `npm adduser`) +See [documentation](https://logion-network.github.io/logion-api/). diff --git a/packages/crossmint/README.md b/packages/crossmint/README.md index 5f3cf6ab..b2a25809 100644 --- a/packages/crossmint/README.md +++ b/packages/crossmint/README.md @@ -2,29 +2,11 @@ This project provides some utility classes enabling the use of the [Crossmint wallet](https://github.com/Crossmint/embed) -with a [logion client](https://github.com/logion-network/logion-api/tree/main/packages/client#readme). +with the [logion client](https://github.com/logion-network/logion-api/tree/main/packages/client#readme). Note that only message signature is supported. So you will be able to authenticate and interact with logion off-chain services, but not submit extrinsics to the logion chain. ## Usage -Install package `@logion/crossmint` with your favorite package manager and start siging content using the extension. - -```typescript -import { CrossmintSigner } from '@logion/crossmint'; - -const crossmint = new CrossmintEVMWalletAdapter({ - apiKey: "YOUR_API_KEY", - chain: BlockchainTypes.ETHEREUM, // Only Ethereum is supported for the moment -}); - -const address = await crossmint.connect(); -if(!address) { - throw new Error("Unable to connect to Crossmint"); -} - -const client = LogionClient.create(...); -const signer = new CrossmintSigner(crossmint); -let authenticatedClient = await client.authenticate([ address ], signer); -``` +See [documentation](https://logion-network.github.io/logion-api/). diff --git a/packages/extension/README.md b/packages/extension/README.md index 36f80cc0..d36e1fc1 100644 --- a/packages/extension/README.md +++ b/packages/extension/README.md @@ -6,18 +6,4 @@ with a [logion client](https://github.com/logion-network/logion-api/tree/main/pa ## Usage -Install package `@logion/extension` with your favorite package manager and start siging content using the extension. - -```typescript -import { enableExtensions, ExtensionSigner } from '@logion/extension'; - -const client = LogionClient.create(...); // Create your logion client - -const register = await enableExtensions("Your app name", [ "polkadot-js" ]); -const signer = new ExtensionSigner(); -register((accounts: InjectedAccount[]) => { - const addresses = accounts.map(account => account.address); - const authenticated = await client.authenticate(addresses, signer); // This will enable authentication by signing with the extension - // Use authenticated to use logion features -}); -``` +See [documentation](https://logion-network.github.io/logion-api/). diff --git a/packages/multiversx/README.md b/packages/multiversx/README.md index 78e24697..16db83ed 100644 --- a/packages/multiversx/README.md +++ b/packages/multiversx/README.md @@ -9,16 +9,4 @@ with logion off-chain services, but not submit extrinsics to the logion chain. ## Usage -Install package `@logion/multiversx` with your favorite package manager and start siging content using the extension. - -```typescript -import { MultiversxSigner } from '@logion/multiversx'; - -const signer = new MultiversxSigner(); -const address = await signer.login(); - -const client = LogionClient.create(...); -const account = client.api.queries.getValidAccountId(address, "Bech32"); - -let authenticatedClient = await client.authenticate([ account ], signer); -``` +See [documentation](https://logion-network.github.io/logion-api/). diff --git a/website/docs/client/authentication.md b/website/docs/client/authentication.md index 53b7fd1e..f9ce6c38 100644 --- a/website/docs/client/authentication.md +++ b/website/docs/client/authentication.md @@ -9,18 +9,23 @@ Below example shows how to use an embedded signer in order to authenticate `clie a [browser extension](/docs/category/extension) should be used instead. ```typescript +import { ValidAccountId } from '@logion/node-api'; import { Keyring } from '@polkadot/api'; const keyring = new Keyring(); const keypair = keyring.addFromUri("0xe5be9a5092b81bca64be81d212e7f2f9eba183bb7a90954f7b76361f6edb5c0a"); // Alice +const accountId = ValidAccountId.polkadot(keypair.address); const signer = new KeyringSigner(keyring); // Authenticate Alice let authenticatedClient = await client.authenticate( - [ keypair.address ], + [ accountId ], signer ); +// Select current account (required if several accounts are authenticated) +authenticatedClient = authenticatedClient.withCurrentAccount(accountId); + // Later on, refresh the session (session's TTL is 1 hour) authenticatedClient = await authenticatedClient.refreshTokens(DateTime.now()); ``` diff --git a/website/docs/client/balance-transactions.md b/website/docs/client/balance-transactions.md index b14ccf9a..ea835711 100644 --- a/website/docs/client/balance-transactions.md +++ b/website/docs/client/balance-transactions.md @@ -53,11 +53,13 @@ You can transfer any amount (must be less than or equal to the balance, taking t to another account: ```typescript -import { PrefixedNumber, KILO } from "@logion/node-api"; +import { Lgnt, ValidAccountId } from "@logion/node-api"; + +const destination = ValidAccountId.polkadot("vQx5kESPn8dWyX4KxMCKqUyCaWUwtui1isX6PVNcZh2Ghjitr"); // Alice balanceState = balanceState.transfer({ + amount: Lgnt.from(42n), // 42 LGNTs + destination, signer, - amount: new PrefixedNumber("2", KILO), - destination: ALICE.address }); ``` diff --git a/website/docs/client/protection.md b/website/docs/client/protection.md index f32fd198..db052451 100644 --- a/website/docs/client/protection.md +++ b/website/docs/client/protection.md @@ -37,14 +37,18 @@ For below example to work, you will need a valid Identity LOC with both alice an const legalOfficers = authenticatedClient.getLegalOfficers(); const locsState = await authenticatedClient.locsState(); -const alice = authenticatedClient.getLegalOfficer("5GrwvaEF5zXb26Fz9rcQpDWS57CtERHpNehXCPcNoHGKutQY"); -const bob = authenticatedClient.getLegalOfficer("5FHneW46xGXgs5mUiveU4sbTyGBzmstUspZC92UhjJM694ty"); +const alice = authenticatedClient.getLegalOfficer( + ValidAccountId.polkadot("vQx5kESPn8dWyX4KxMCKqUyCaWUwtui1isX6PVNcZh2Ghjitr") +); +const bob = authenticatedClient.getLegalOfficer( + ValidAccountId.polkadot("vQvWaxNDdzuX5N3qSvGMtjdHcQdw1TAcPNgx4S1Utd3MTxYeN") +); const aliceLoc = locsState.closedLocs.Identity.find( - loc => loc.data().ownerAddress === alice.address + loc => loc.data().ownerAccountId.equals(alice.account) && loc.data().voidInfo === undefined ); const bobLoc = locsState.closedLocs.Identity.find( - loc => loc.data().ownerAddress === bob.address + loc => loc.data().ownerAccountId.equals(bob.account) && loc.data().voidInfo === undefined ); ``` @@ -76,9 +80,9 @@ let vaultState = await activeProtection.vaultState(); const vaultAddress = vaultState.vaultAddress; vaultState = await vaultState.createVaultTransferRequest({ legalOfficer: alice, - amount: new PrefixedNumber("1", NONE), - destination: REQUESTER_ADDRESS, - signer + amount: Lgnt.from(1n), + destination: ValidAccountId.polkadot("vQvZF2YMgKuQhzfF7T3xDjHjuEmcPSUVEoUDPy1mzuSXzFgca"), + signer, }); const pendingRequest = vaultState.pendingVaultTransferRequests[0]; ``` @@ -120,7 +124,7 @@ Recovery must be requested to the **same Legal Officers** who accepted to protec const noProtection = await authenticatedClient.protectionState() as NoProtection; const pending = await noProtection.requestRecovery({ payload: { - recoveredAddress: REQUESTER_ADDRESS, + recoveredAddress: ValidAccountId.polkadot("vQv6hV73oeb7cJHXaWsw3K4bmgHjzxj9zm3nZtZPsxbsvhcTk"), legalOfficer1: alice, legalOfficer2: bob, requesterIdentityLoc1: aliceLoc, @@ -155,7 +159,7 @@ const claimed = await pendingRecovery.claimRecovery(signer); const recoveredBalance = await claimed.recoveredBalanceState(); await recoveredBalance.transfer({ signer, - destination: NEW_ADDRESS, + destination: ValidAccountId.polkadot("vQuQm7K3Qt1nQYDzqQzCPQj6b4AQFPZgD5FLnEpBTvCx1rVix"), amount: recoveredBalance.balances[0].available, }); ``` diff --git a/website/docs/extension/crossmint.md b/website/docs/extension/crossmint.md new file mode 100644 index 00000000..f6a8e6d7 --- /dev/null +++ b/website/docs/extension/crossmint.md @@ -0,0 +1,36 @@ +--- +sidebar_position: 3 +--- + +# Crossmint + +![Crossmint extension](/img/crossmint.png) + +This project provides some utility classes enabling the use of +[Crossmint wallet](https://github.com/Crossmint/embed) +with the [Logion client](/docs/category/client). + +Note that only message signature is supported. So you will be able to authenticate and interact +with logion off-chain services, but not submit extrinsics to the logion chain. + +## Usage + +Install package `@logion/crossmint` with your favorite package manager and start signing content using the extension. + +```typescript +import { CrossmintSigner } from '@logion/crossmint'; + +const crossmint = new CrossmintEVMWalletAdapter({ + apiKey: "YOUR_API_KEY", + chain: BlockchainTypes.ETHEREUM, // Only Ethereum is supported for the moment +}); + +const address = await crossmint.connect(); +if(!address) { + throw new Error("Unable to connect to Crossmint"); +} + +const signer = new CrossmintSigner(crossmint); +const account = ValidAccountId.ethereum(address); +let authenticatedClient = await client.authenticate([ account ], signer); +``` diff --git a/website/docs/extension/multiversx.md b/website/docs/extension/multiversx.md new file mode 100644 index 00000000..f1ba95e3 --- /dev/null +++ b/website/docs/extension/multiversx.md @@ -0,0 +1,29 @@ +--- +sidebar_position: 4 +--- + +# MultiversX + +![MultiversX](/img/multiversx.png) + +This project provides some utility classes enabling the use of +[MultiversX wallet](hhttps://github.com/multiversx/mx-sdk-js-extension-provider) +with the [Logion client](/docs/category/client). + +Note that only message signature is supported. So you will be able to authenticate and interact +with logion off-chain services, but not submit extrinsics to the logion chain. + +## Usage + +Install package `@logion/multiversx` with your favorite package manager and start signing content using the extension. + +```typescript +import { MultiversxSigner } from '@logion/multiversx'; + +const signer = new MultiversxSigner(); +const address = await signer.login(); + +const account = ValidAccountId.bech32(address); + +let authenticatedClient = await client.authenticate([ account ], signer); +``` diff --git a/website/docs/extension/polkadot-js.md b/website/docs/extension/polkadot-js.md index 374ddd15..58485a55 100644 --- a/website/docs/extension/polkadot-js.md +++ b/website/docs/extension/polkadot-js.md @@ -2,9 +2,9 @@ sidebar_position: 1 --- -# polkadot\{.js\} +# Polkadot -![polkadot\{.js\} extension](/img/polkadot.png) +![Polkadot extension](/img/polkadot.png) This project provides some utility classes enabling the use of the [Polkadot JS extension](https://github.com/polkadot-js/extension#readme) @@ -17,13 +17,14 @@ Start signing content using the extension. ```typescript import { getAccounts, ExtensionSigner } from '@logion/extension'; +import { ValidAccountId } from "@logion/node-api"; const signer = new ExtensionSigner(); const injectedAccounts = await getAccounts( "Your app name", [ "polkadot-js", "subwallet-js" ], // A list of extensions ); -const addresses = injectedAccounts.map(account => account.address); +const addresses = injectedAccounts.map(account => ValidAccountId.polkadot(account.address)); const authenticated = await client.authenticate(addresses, signer); // Pass `signer` as an argument when needed diff --git a/website/docusaurus.config.js b/website/docusaurus.config.js index a9650d36..0b654014 100644 --- a/website/docusaurus.config.js +++ b/website/docusaurus.config.js @@ -79,14 +79,14 @@ const config = { label: 'Introduction', }, { - to: '/docs/category/extension', + to: '/docs/category/client', position: 'left', - label: 'Extension', + label: 'Client', }, { - to: '/docs/category/client', + to: '/docs/category/extension', position: 'left', - label: 'Client', + label: 'Extension', }, { to: '/docs/reference/modules', diff --git a/website/static/img/crossmint.png b/website/static/img/crossmint.png new file mode 100644 index 00000000..a2155f00 Binary files /dev/null and b/website/static/img/crossmint.png differ diff --git a/website/static/img/multiversx.png b/website/static/img/multiversx.png new file mode 100644 index 00000000..8b49c2fa Binary files /dev/null and b/website/static/img/multiversx.png differ