Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add flutter support + improve language-specific aspects #179

Merged
merged 3 commits into from
Jul 13, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 12 additions & 0 deletions docs/building-apps/wallet/component/header.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { LanguageButtons } from "@site/src/components/LanguageButtons";
import { WalletGuideWarn } from "@site/src/components/WalletGuideWarn";

<LanguageButtons />

:::info

This guide is available on three different programming languages: Typescript, Kotlin and Flutter (Dart). You can change the shown version on each page via the buttons above.

:::

<WalletGuideWarn WIPLangs={props.WIPLangs} />
13 changes: 13 additions & 0 deletions docs/building-apps/wallet/component/kt/global_signer.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
import { CodeExample } from "@site/src/components/CodeExample";

Finally, with the approach above we define the signer and client domain per request. If you want to define it once and use it for every authentication call your application is making, you can do so via changing the configuration:

<CodeExample>

```kotlin
val appCfg = ApplicationConfiguration(WalletSigner.DomainSigner("https://my-domain.com/sign"), "my-domain.com")
```

</CodeExample>

This is particularly useful for integrating with multiple anchors.
14 changes: 6 additions & 8 deletions docs/building-apps/wallet/intro.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,11 @@ sidebar_position: 20

import { LanguageSpecific } from "@site/src/components/LanguageSpecific";
import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCodeExample";
import { LanguageButtons } from "@site/src/components/LanguageButtons";
import Header from "./component/header.mdx";
import KtInstall from "./component/kt_install.mdx";
import TsInstall from "./component/ts_install.mdx";

<LanguageButtons />

:::info

This guide is available on two different programming languages: Typescript and Kotlin. You can change the shown on each page via the buttons above.

:::
<Header WIPLangs={["ts", "dart"]} />

## Installation

Expand All @@ -37,6 +31,10 @@ val wallet = Wallet(StellarConfiguration.Testnet)
let wallet = walletSdk.Wallet.TestNet();
```

```flutter
final StellarSDK sdk = StellarSDK.TESTNET;
```

</CodeExample>

The wallet instance can be further configured. For example, to connect to the public network:
Expand Down
10 changes: 2 additions & 8 deletions docs/building-apps/wallet/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -4,15 +4,9 @@ sidebar_position: 10
---

import { CodeExample } from "@site/src/components/CodeExample";
import { LanguageButtons } from "@site/src/components/LanguageButtons";
import Header from "./component/header.mdx";
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we actually remove the header in the overview since there are no code examples?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's there for user to get familiar with the UX, I want to keep it just for this reason.
If you think it's confusing/clunky I can remove it


<LanguageButtons />

:::info

This guide is available on two different programming languages: Typescript and Kotlin. You can change the shown version on each page via the buttons above.

:::
<Header />

In this guide we will use the Wallet SDK to integrate with the Stellar blockchain and connect to anchors.

Expand Down
36 changes: 12 additions & 24 deletions docs/building-apps/wallet/sep10.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,17 +3,13 @@ title: Stellar Authentication
sidebar_position: 40
---

import { CodeExample } from "@site/src/components/CodeExample";
import { LanguageSpecific } from "@site/src/components/LanguageSpecific";
import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCodeExample";
import { CodeExample as NonWalletCodeExample } from "@site/src/components/CodeExample";
import Header from "./component/header.mdx";
import GlobalClientSigner from "./component/kt/global_signer.mdx";

import { LanguageButtons } from "@site/src/components/LanguageButtons";

<LanguageButtons />

:::info

This guide is available on two different programming languages: Typescript and Kotlin. You can change the shown version on each page via the buttons above.

:::
<Header WIPLangs={["dart"]} />

Wallets connect to anchors using a standard way of authentication via the Stellar network defined by the [SEP-10] standard.

Expand Down Expand Up @@ -177,17 +173,9 @@ const demoWalletSigner: WalletSigner = {

</CodeExample>

Finally, with the approach above we define the signer and client domain per request. If you want to define it once and use it for every authentication call your application is making, you can do so via changing the configuration:

<CodeExample>

```kotlin
val appCfg = ApplicationConfiguration(WalletSigner.DomainSigner("https://my-domain.com/sign"), "my-domain.com")
```

</CodeExample>
[//]: # "TODO: update after WAL-882 is completed"

This is particularly useful for integrating with multiple anchors.
<LanguageSpecific kt={<GlobalClientSigner />} />

### Server Side

Expand All @@ -197,7 +185,7 @@ First, generate a new authentication key that will be used as a `client_domain`

Next, create a `SEP-1` toml file placed under `<your domain>/.well-known/stellar.toml` with the following content:

<CodeExample>
<NonWalletCodeExample>

```toml
ACCOUNTS = [ "Authentication public key (address)" ]
Expand All @@ -206,13 +194,13 @@ SIGNING_KEY = "Authentication public key (address)"
NETWORK_PASSPHRASE = "Test SDF Network ; September 2015"
```

</CodeExample>
</NonWalletCodeExample>

Don't forget to change the network passphrase for Mainnet deployment.

Finally, let's add server implementation. This sample implementation uses express framework:

<CodeExample>
<NonWalletCodeExample>

```javascript
app.post("/sign", (req, res) => {
Expand All @@ -237,7 +225,7 @@ app.post("/sign", (req, res) => {
});
```

</CodeExample>
</NonWalletCodeExample>

You can see full example [here](https://github.com/stellar/stellar-demo-wallet/blob/52071629f8d29470b61799bef9519776d9c252d2/packages/demo-wallet-server/src/index.ts). As mentioned before, this sample implementation doesn't have any protection against unauthorized requests, so you must add authorization checks as part of the request.

Expand Down
12 changes: 3 additions & 9 deletions docs/building-apps/wallet/sep24.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,10 @@ title: Hosted Deposit and Withdrawal
sidebar_position: 50
---

import { CodeExample } from "@site/src/components/CodeExample";
import { LanguageButtons } from "@site/src/components/LanguageButtons";
import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCodeExample";
import Header from "./component/header.mdx";

<LanguageButtons />

:::info

This guide is available on two different programming languages: Typescript and Kotlin. You can change the shown version on each page via the buttons above.

:::
<Header WIPLangs={["ts", "dart"]} />

The [SEP-24] standard defines the standard way for anchors and wallets to interact on behalf of users. Wallets use this standard to facilitate exchanges between on-chain assets (such as stablecoins) and off-chain assets (such as fiat, or other network assets such as BTC).

Expand Down
12 changes: 3 additions & 9 deletions docs/building-apps/wallet/stellar.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,10 @@ title: Stellar Network
sidebar_position: 30
---

import { CodeExample } from "@site/src/components/CodeExample";
import { LanguageButtons } from "@site/src/components/LanguageButtons";
import { WalletCodeExample as CodeExample } from "@site/src/components/WalletCodeExample";
import Header from "./component/header.mdx";

<LanguageButtons />

:::info

This guide is available on two different programming languages: Typescript and Kotlin. You can change the shown version on each page via the buttons above.

:::
<Header WIPLangs={["ts", "dart"]} />

In the previous section we learned how to create a wallet and a `Stellar` object that provides a connection to Horizon. In this section, we will look at the usages of this class.

Expand Down
3 changes: 2 additions & 1 deletion docusaurus.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -256,7 +256,8 @@ const config = {
"json5",
"python",
"docker",
"kotlin"
"kotlin",
"dart"
],
},
}),
Expand Down
2 changes: 2 additions & 0 deletions src/components/CodeExample.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ export const CODE_LANGS = {
bash: 'bash',
cpp: 'C++',
curl: 'cURL',
dart: 'Flutter',
flutter: 'Flutter',
docker: 'Dockerfile',
go: 'Go',
html: 'html',
Expand Down
12 changes: 10 additions & 2 deletions src/components/LanguageButtons.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,23 @@
import React from "react";
import BrowserOnly from '@docusaurus/BrowserOnly';
import {useColorMode} from '@docusaurus/theme-common';
import Kotlin from '@site/static/img/kt.png'
import KotlinDark from '@site/static/img/kt-dark.png'
import Typescript from '@site/static/img/ts.png'
import Flutter from '@site/static/img/flutter.png'
import FlutterDark from '@site/static/img/flutter-dark.png'

export const LanguageButtons = () => {
const {colorMode} = useColorMode();
const isDark = colorMode === 'dark'

return (
<BrowserOnly>
{() =>
<div style={{gap: "0.6rem", display: "flex", marginBottom: "1rem"}}>
<div style={{gap: "1rem", display: "flex", marginBottom: "1rem"}}>
<img src={Typescript} onClick={() => setCookie("ts")} style={{maxHeight: "1.2rem"}}/>
<img src={Kotlin} onClick={() => setCookie("kt")} style={{maxHeight: "1.1rem"}}/>
<img src={isDark ? KotlinDark : Kotlin} onClick={() => setCookie("kt")} style={{maxHeight: "1.1rem"}}/>
<img src={isDark ? FlutterDark : Flutter} onClick={() => setCookie("dart")} style={{maxHeight: "1.2rem"}}/>
</div>
}
</BrowserOnly>
Expand Down
14 changes: 9 additions & 5 deletions src/components/LanguageSpecific.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,17 @@ import React from "react";
import BrowserOnly from '@docusaurus/BrowserOnly';

type LanguageProps = {
kt: JSX.Element;
ts: JSX.Element;
kt?: JSX.Element;
ts?: JSX.Element;
flutter?: JSX.Element;
fallback?: JSX.Element;
};

export const walletDefaultLang = "ts"

export const LanguageSpecific: React.FC<LanguageProps> = (props) => {
return (
<BrowserOnly fallback={getToShow(props, null)}>
<BrowserOnly fallback={props.fallback || getToShow(props, null)}>
{() => getToShow(props, getCookie())}
</BrowserOnly>
);
Expand All @@ -24,9 +26,11 @@ const getToShow = (props: LanguageProps, cookie: String) => {
}

if (cookie == "kt") {
toShow = props.kt
toShow = props.kt || <></>
} else if (cookie == "ts") {
toShow = props.ts
toShow = props.ts || <></>
} else if (cookie == "dart") {
toShow = props.flutter || <></>
}

return toShow
Expand Down
28 changes: 22 additions & 6 deletions src/components/WalletCodeExample.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,10 @@ import {Exception} from "sass";

// TODO: when TS docs are ready set to false
const ALLOW_EMPTY_DOCS = true
// Set to true for local debugging
const SHOW_ALL = false

const WALLET_LANGS = ["kt", "ts"]
const WALLET_LANGS = ["kt", "ts", "dart"]

type WalletCodeExampleProps = {
children: React.ReactElement
Expand All @@ -22,14 +24,18 @@ export const WalletCodeExample: React.FC<WalletCodeExampleProps> = ({children})
</BrowserOnly>
}

const getTabs = (children: React.ReactElement, lang: String) => {
const defaultVal = CODE_LANGS[lang]
const getTabs = (children: React.ReactElement, targetLanguage: String) => {
const defaultVal = CODE_LANGS[targetLanguage]

const tabs = React.Children.map(children, (child, index) => {
const codeProps = child.props.children.props;
const {className = ''} = codeProps;

const [, language] = className.split('-');
let [, language] = className.split('-');

if (language === "flutter") {
language = "dart"
}

return (
<TabItem
Expand All @@ -50,7 +56,6 @@ const getTabs = (children: React.ReactElement, lang: String) => {

if (tabs.filter((x) => x.props.value === language).length === 0) {
if (ALLOW_EMPTY_DOCS) {

tabs.push(<TabItem
key={language}
value={language}
Expand All @@ -67,10 +72,21 @@ const getTabs = (children: React.ReactElement, lang: String) => {
}
}

let toShowTabs = tabs

if (!SHOW_ALL) {
for (let i = 0; i < tabs.length; i++) {
const language = CODE_LANGS[targetLanguage]
if (tabs[i].props.value === language) {
toShowTabs = [tabs[i]]
}
}
}

const gid = "wallet-lang" + defaultVal
// const gid = "p-wallet" + defaultVal + Math.random()

return (<Tabs groupId={gid}>
{tabs}
{toShowTabs}
</Tabs>)
}
24 changes: 24 additions & 0 deletions src/components/WalletGuideWarn.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import React from "react";
import Admonition from '@theme/Admonition';
import {LanguageButtons} from "./LanguageButtons";
import {CODE_LANGS} from "./CodeExample";
import {LanguageSpecific} from "./LanguageSpecific";

type WalletGuideWarnProps = {
WIPLangs?: String[]
};

export const WalletGuideWarn: React.FC<WalletGuideWarnProps> = (props) => {
const langs = (props.WIPLangs || []).map(v => CODE_LANGS[v.toLowerCase()])
const admonition = <Admonition type={"danger"} title={"Important"}>Documentation for this language is currently work in progress. Some of information may not be applicable for this language, or missing. Code samples may be incomplete.</Admonition>

const kt = langs.indexOf("Kotlin") != -1 ? admonition : <></>
const ts = langs.indexOf("TypeScript") != -1 ? admonition: <></>
const flutter = langs.indexOf("Flutter") != -1 ? admonition : <></>

return <LanguageSpecific kt={kt} ts={ts} flutter={flutter} fallback={<></>}/>
};




Binary file added static/img/flutter-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/flutter.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/img.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added static/img/kt-dark.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file modified static/img/ts.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 0 additions & 1 deletion static/img/ts.svg

This file was deleted.