├── .editorconfig
├── .github
└── workflows
│ ├── buf-push.yml
│ └── release.yml
├── .gitignore
├── .releaserc
├── .tool-versions
├── .vscode
└── extensions.json
├── LICENSE.md
├── Makefile
├── README.md
├── api
├── .gitignore
├── gen
│ ├── csharp
│ │ ├── Gnonativetypes.cs
│ │ ├── Rpc.cs
│ │ └── RpcGrpc.cs
│ ├── es
│ │ ├── gnonativetypes_pb.ts
│ │ └── rpc_pb.ts
│ └── go
│ │ ├── _goconnect
│ │ └── rpc.connect.go
│ │ ├── error.go
│ │ ├── gnonativetypes.pb.go
│ │ └── rpc.pb.go
├── gnonativetypes.proto
├── gnonativetypes
│ ├── gnonativetypes.go
│ └── package.go
├── package-lock.json
├── package.json
└── rpc.proto
├── buf.gen.yaml
├── buf.yaml
├── docs
└── getting-started
│ └── create-new-app.md
├── examples
├── csharp-dotnet
│ └── UnityClient
│ │ └── README.md
├── go
│ └── goclient
│ │ ├── README.md
│ │ └── main.go
└── js
│ ├── expo
│ ├── gnoboard
│ │ ├── .eslintrc.json
│ │ ├── .gitignore
│ │ ├── .prettierignore
│ │ ├── .prettierrc
│ │ ├── .storybook
│ │ │ ├── index.js
│ │ │ ├── main.js
│ │ │ ├── preview.js
│ │ │ ├── stories
│ │ │ │ └── Button
│ │ │ │ │ ├── Button.js
│ │ │ │ │ └── Button.stories.js
│ │ │ └── storybook.requires.js
│ │ ├── App.tsx
│ │ ├── Makefile
│ │ ├── README.md
│ │ ├── app.json
│ │ ├── assets
│ │ │ ├── adaptive-icon.png
│ │ │ ├── favicon.png
│ │ │ ├── icon.png
│ │ │ └── splash.png
│ │ ├── babel.config.js
│ │ ├── metro.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── src
│ │ │ ├── components
│ │ │ │ ├── account
│ │ │ │ │ ├── AccountBalance.stories.tsx
│ │ │ │ │ ├── AccountBalance.tsx
│ │ │ │ │ ├── CurrentAccount.stories.tsx
│ │ │ │ │ ├── CurrentAccoutn.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── alert
│ │ │ │ │ ├── Alert.stories.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── buttons
│ │ │ │ │ ├── Buttons.stories.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── change-network
│ │ │ │ │ ├── ChangeNetwork.stories.tsx
│ │ │ │ │ ├── network-list-item
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── network-list
│ │ │ │ │ │ └── index.tsx
│ │ │ │ ├── common
│ │ │ │ │ ├── side-menu-account-item
│ │ │ │ │ │ └── side-menu-account-item.tsx
│ │ │ │ │ └── side-menu-account-list
│ │ │ │ │ │ └── side-menu-account-list.tsx
│ │ │ │ ├── consoleview
│ │ │ │ │ ├── index.tsx
│ │ │ │ │ └── styles.ts
│ │ │ │ ├── icons
│ │ │ │ │ ├── ArrowLeft.tsx
│ │ │ │ │ ├── CheckMark.tsx
│ │ │ │ │ ├── Close.tsx
│ │ │ │ │ ├── Exclamation.tsx
│ │ │ │ │ └── index.ts
│ │ │ │ ├── modal
│ │ │ │ │ ├── Modal.stories.tsx
│ │ │ │ │ ├── ModalConfirm.stories.tsx
│ │ │ │ │ ├── ModalConfirm.tsx
│ │ │ │ │ ├── ModalContent.tsx
│ │ │ │ │ ├── ModalHeader.tsx
│ │ │ │ │ └── index.ts
│ │ │ │ ├── pages
│ │ │ │ │ ├── Body.tsx
│ │ │ │ │ ├── Container.tsx
│ │ │ │ │ ├── Header.tsx
│ │ │ │ │ └── index.ts
│ │ │ │ ├── row
│ │ │ │ │ ├── Ruller.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── seedbox
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── textinput
│ │ │ │ │ ├── Input.stories.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ └── texts
│ │ │ │ │ └── index.ts
│ │ │ ├── provider
│ │ │ │ └── gnoboard-provider.tsx
│ │ │ ├── resources
│ │ │ │ └── chains
│ │ │ │ │ └── chains.json
│ │ │ ├── router
│ │ │ │ ├── custom-router.tsx
│ │ │ │ └── path.ts
│ │ │ ├── screens
│ │ │ │ ├── BlankPage.tsx
│ │ │ │ ├── board
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── certify
│ │ │ │ │ ├── create-password
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ ├── enter-seed
│ │ │ │ │ │ └── index.tsx
│ │ │ │ │ └── your-seed-phrase
│ │ │ │ │ │ └── index.tsx
│ │ │ │ ├── change-network
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── devmode
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── loading
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── remove-account
│ │ │ │ │ ├── confirm.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ ├── switch-accounts
│ │ │ │ │ ├── ReenterPassword.stories.tsx
│ │ │ │ │ ├── ReenterPassword.tsx
│ │ │ │ │ └── index.tsx
│ │ │ │ └── wallet
│ │ │ │ │ └── home
│ │ │ │ │ └── index.tsx
│ │ │ ├── styles
│ │ │ │ ├── colors.ts
│ │ │ │ ├── index.ts
│ │ │ │ └── screens.ts
│ │ │ └── types
│ │ │ │ ├── index.ts
│ │ │ │ └── types.ts
│ │ └── tsconfig.json
│ └── hello
│ │ ├── .gitignore
│ │ ├── App.tsx
│ │ ├── app.json
│ │ ├── assets
│ │ ├── adaptive-icon.png
│ │ ├── favicon.png
│ │ ├── icon.png
│ │ └── splash.png
│ │ ├── babel.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ └── tsconfig.json
│ ├── react-native
│ └── hello
│ │ ├── .bundle
│ │ └── config
│ │ ├── .eslintrc.js
│ │ ├── .gitignore
│ │ ├── .prettierrc.js
│ │ ├── .watchmanconfig
│ │ ├── App.tsx
│ │ ├── Gemfile
│ │ ├── Gemfile.lock
│ │ ├── GoBridge
│ │ ├── GoBridge.native.ts
│ │ ├── GoBridge.ts
│ │ ├── GoBridgeInterface.ts
│ │ ├── index.ts
│ │ └── types.ts
│ │ ├── README.md
│ │ ├── __tests__
│ │ └── App.test.tsx
│ │ ├── android
│ │ ├── app
│ │ │ ├── build.gradle
│ │ │ ├── debug.keystore
│ │ │ ├── proguard-rules.pro
│ │ │ └── src
│ │ │ │ ├── debug
│ │ │ │ └── AndroidManifest.xml
│ │ │ │ └── main
│ │ │ │ ├── AndroidManifest.xml
│ │ │ │ ├── java
│ │ │ │ ├── com
│ │ │ │ │ └── hello
│ │ │ │ │ │ ├── MainActivity.kt
│ │ │ │ │ │ └── MainApplication.kt
│ │ │ │ └── land
│ │ │ │ │ └── gno
│ │ │ │ │ ├── gobridge
│ │ │ │ │ ├── GoBridgeModule.java
│ │ │ │ │ ├── GoBridgePackage.java
│ │ │ │ │ └── JavaPromiseBlock.java
│ │ │ │ │ └── rootdir
│ │ │ │ │ ├── RootDirModule.java
│ │ │ │ │ └── RootDirPackage.java
│ │ │ │ └── res
│ │ │ │ ├── drawable
│ │ │ │ └── rn_edit_text_material.xml
│ │ │ │ ├── mipmap-hdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-mdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ ├── mipmap-xxxhdpi
│ │ │ │ ├── ic_launcher.png
│ │ │ │ └── ic_launcher_round.png
│ │ │ │ └── values
│ │ │ │ ├── strings.xml
│ │ │ │ └── styles.xml
│ │ ├── build.gradle
│ │ ├── gradle.properties
│ │ ├── gradle
│ │ │ └── wrapper
│ │ │ │ ├── gradle-wrapper.jar
│ │ │ │ └── gradle-wrapper.properties
│ │ ├── gradlew
│ │ ├── gradlew.bat
│ │ └── settings.gradle
│ │ ├── api
│ │ ├── GnoNativeApi.ts
│ │ ├── index.ts
│ │ └── types.ts
│ │ ├── app.json
│ │ ├── babel.config.js
│ │ ├── grpc
│ │ ├── client.ts
│ │ ├── error.ts
│ │ ├── transport_native.ts
│ │ └── transport_web.ts
│ │ ├── index.js
│ │ ├── ios
│ │ ├── .xcode.env
│ │ ├── Podfile
│ │ ├── Podfile.lock
│ │ ├── Sources
│ │ │ ├── Bridge
│ │ │ │ ├── GoBridge.m
│ │ │ │ ├── GoBridge.swift
│ │ │ │ └── PromiseBlock.swift
│ │ │ └── RootDir
│ │ │ │ ├── RootDir.m
│ │ │ │ └── RootDir.swift
│ │ ├── hello.xcodeproj
│ │ │ ├── project.pbxproj
│ │ │ └── xcshareddata
│ │ │ │ └── xcschemes
│ │ │ │ └── hello.xcscheme
│ │ ├── hello.xcworkspace
│ │ │ ├── contents.xcworkspacedata
│ │ │ └── xcshareddata
│ │ │ │ └── IDEWorkspaceChecks.plist
│ │ ├── hello
│ │ │ ├── AppDelegate.h
│ │ │ ├── AppDelegate.mm
│ │ │ ├── Images.xcassets
│ │ │ │ ├── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ │ └── Contents.json
│ │ │ ├── Info.plist
│ │ │ ├── LaunchScreen.storyboard
│ │ │ ├── PrivacyInfo.xcprivacy
│ │ │ ├── hello-Bridging-Header.h
│ │ │ └── main.m
│ │ └── helloTests
│ │ │ ├── Info.plist
│ │ │ └── helloTests.m
│ │ ├── jest.config.js
│ │ ├── metro.config.js
│ │ ├── package-lock.json
│ │ ├── package.json
│ │ ├── provider
│ │ └── gnonative-provider.tsx
│ │ └── tsconfig.json
│ └── wails
│ └── README.md
├── expo
├── .eslintrc.js
├── .gitignore
├── .npmignore
├── .npmrc
├── .prettierrc.js
├── Makefile
├── README.md
├── android
│ ├── build.gradle
│ └── src
│ │ └── main
│ │ ├── AndroidManifest.xml
│ │ └── java
│ │ └── land
│ │ └── gno
│ │ └── gnonative
│ │ ├── GnonativeModule.kt
│ │ ├── GnonativeView.kt
│ │ ├── GoBridgeError.kt
│ │ └── JavaPromiseBlock.kt
├── example
│ ├── .gitignore
│ ├── App.tsx
│ ├── README.md
│ ├── app.json
│ ├── assets
│ │ ├── adaptive-icon.png
│ │ ├── favicon.png
│ │ ├── icon.png
│ │ └── splash.png
│ ├── babel.config.js
│ ├── metro.config.js
│ ├── package-lock.json
│ ├── package.json
│ ├── tsconfig.json
│ └── webpack.config.js
├── expo-module.config.json
├── ios
│ ├── GnoError.swift
│ ├── Gnonative.podspec
│ ├── GnonativeModule.swift
│ ├── GnonativeView.swift
│ └── PromiseBlock.swift
├── package-lock.json
├── package.json
├── src
│ ├── Gnonative.types.ts
│ ├── GnonativeModule.ts
│ ├── GnonativeModule.web.ts
│ ├── GnonativeView.tsx
│ ├── GnonativeView.web.tsx
│ ├── GoBridge.ts
│ ├── api
│ │ ├── GnoNativeApi.ts
│ │ ├── index.ts
│ │ └── types.ts
│ ├── grpc
│ │ ├── client.ts
│ │ ├── error.ts
│ │ └── transport_native.ts
│ ├── index.ts
│ └── provider
│ │ └── gnonative-provider.tsx
└── tsconfig.json
├── framework
├── .gitignore
└── service
│ ├── bridge.go
│ └── service_client.go
├── gen.sum
├── go.mod
├── go.sum
├── goserver
├── README.md
└── main.go
├── misc
└── genproto
│ ├── gen.sum
│ └── genproto.go
├── service
├── api.go
├── config.go
├── service.go
└── tools.go
└── templates
├── App.tsx
├── babel.config.js
├── es
├── use-gno-web.ts
└── use-gno.ts
├── images
└── logo-universal.png
├── metro.config.js
├── transport_web.ts
└── tsconfig.json
/.editorconfig:
--------------------------------------------------------------------------------
1 | root = true
2 |
3 | [*]
4 | charset = utf-8
5 |
6 | end_of_line = lf
7 | insert_final_newline = true
8 | trim_trailing_whitespace = true
9 |
10 | indent_style = space
11 | indent_size = 4
12 |
13 | [Makefile]
14 | indent_style = tab
15 |
16 | [*.go]
17 | indent_style = tab
18 |
19 | [*.proto]
20 | indent_size = 2
21 |
22 | [*.kt]
23 | indent_size = 2
24 |
25 | [*.swift]
26 | indent_size = 4
27 |
28 | [*.tmpl]
29 | indent_size = 2
30 |
31 | [*.{js,jsx,cjs,ts,tsx}]
32 | indent_size = 2
33 | block_comment_start = /*
34 | block_comment_end = */
35 |
36 | [*.html]
37 | indent_size = 2
38 |
39 | [*.bat]
40 | end_of_line = crlf
41 |
42 | [*.{json,yml,yaml}]
43 | indent_size = 2
44 |
45 | [.{babelrc,eslintrc}]
46 | indent_size = 2
47 |
48 | [{Fastfile,.buckconfig,BUCK}]
49 | indent_size = 2
50 |
51 | [*.diff]
52 | indent_size = 1
53 |
54 | [*.m]
55 | indent_size = 1
56 | indent_style = space
57 | block_comment_start = /**
58 | block_comment = *
59 | block_comment_end = */
60 |
61 | [*.java]
62 | indent_size = 4
63 | indent_style = space
64 | block_comment_start = /**
65 | block_comment = *
66 | block_comment_end = */
67 |
--------------------------------------------------------------------------------
/.github/workflows/buf-push.yml:
--------------------------------------------------------------------------------
1 | name: buf-push
2 | on:
3 | push:
4 | branches:
5 | - main
6 |
7 | # from https://docs.buf.build/ci-cd/github-actions#buf-push
8 | jobs:
9 | buf-release:
10 | runs-on: ubuntu-latest
11 | steps:
12 | - uses: actions/checkout@v4
13 | - uses: bufbuild/buf-setup-action@v1
14 | # @TODO(gfanton): enable this ?
15 | # - uses: bufbuild/buf-lint-action@v1
16 | # - uses: bufbuild/buf-breaking-action@v1
17 | # with:
18 | # # The 'main' branch of the GitHub repository that defines the module.
19 | # against: "https://github.com/${GITHUB_REPOSITORY}.git#branch=main,ref=HEAD~1"
20 | - uses: bufbuild/buf-push-action@v1
21 | with:
22 | input: "api"
23 | buf_token: ${{ secrets.BUF_TOKEN }}
24 |
--------------------------------------------------------------------------------
/.github/workflows/release.yml:
--------------------------------------------------------------------------------
1 | name: Semantic Release
2 | on:
3 | push:
4 | branches:
5 | - main
6 | workflow_dispatch:
7 | inputs:
8 | debug_enabled:
9 | type: boolean
10 | description: "Run the build with tmate debugging enabled (https://github.com/marketplace/actions/debugging-with-tmate)"
11 | required: false
12 | default: false
13 | jobs:
14 | semantic-release:
15 | runs-on: macos-latest
16 | timeout-minutes: 20
17 | steps:
18 | - name: Checkout
19 | uses: actions/checkout@v4
20 |
21 | - name: Setup tmate session
22 | uses: mxschmitt/action-tmate@v3
23 | with:
24 | detached: true
25 | limit-access-to-actor: true
26 | if: ${{ github.event_name == 'workflow_dispatch' && inputs.debug_enabled }}
27 |
28 | - name: Setup asdf
29 | uses: ynab/asdf-action@v1.2
30 | with:
31 | version: 0.16.7
32 |
33 | - name: Setup Go version
34 | run: |
35 | asdf plugin add golang
36 | asdf install golang
37 | echo "go_version=$(asdf current golang | xargs | cut -d ' ' -f 6)" >> $GITHUB_ENV
38 |
39 | - name: Setup Node version
40 | run: |
41 | asdf plugin add nodejs
42 | asdf install nodejs
43 | echo "node_version=$(asdf current nodejs | xargs | cut -d ' ' -f 6)" >> $GITHUB_ENV
44 |
45 | - name: Set nodejs as global exec
46 | run: |
47 | asdf set -u nodejs ${{ env.node_version }}
48 |
49 | - name: Cache go modules
50 | uses: actions/cache@v4
51 | with:
52 | path: ~/go/pkg/mod
53 | key: ${{ runner.os }}-go-${{ env.go_version }}-${{ hashFiles('**/go.sum') }}
54 | restore-keys: ${{ runner.os }}-go-${{ env.go_version }}-
55 |
56 | - name: Cache node_modules
57 | id: node_modules-cache
58 | uses: actions/cache@v4
59 | with:
60 | path: ./expo/node_modules
61 | key: ${{ runner.OS }}-node-${{ env.node_version }}-${{ hashFiles('expo/package-lock.json') }}
62 | restore-keys: ${{ runner.OS }}-node-${{ env.node_version }}-
63 |
64 | - name: Compile frameworks
65 | working-directory: expo
66 | run: make build
67 |
68 | - name: Install NPM dependencies
69 | working-directory: expo
70 | run: npm install
71 |
72 | - name: Semantic Release
73 | uses: cycjimmy/semantic-release-action@v4
74 | with:
75 | working_directory: ./expo
76 | env:
77 | GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
78 | NPM_TOKEN: ${{ secrets.NPM_TOKEN }}
79 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # OSX
2 | #
3 | .DS_Store
4 |
5 | # Cache
6 | .cache
7 | .eslintcache
8 |
9 | # VSCode
10 | .vscode/
11 | jsconfig.json
12 |
13 | # Ignore any node_modules dir
14 | node_modules/
15 |
--------------------------------------------------------------------------------
/.releaserc:
--------------------------------------------------------------------------------
1 | {
2 | "branches": ["main"]
3 | }
4 |
--------------------------------------------------------------------------------
/.tool-versions:
--------------------------------------------------------------------------------
1 | nodejs 22.8.0
2 | ruby 3.2.2
3 | cocoapods 1.15.2
4 | java openjdk-17.0.2
5 | yarn 1.22.19
6 | golang 1.23.7
7 | buf 1.53.0
8 |
--------------------------------------------------------------------------------
/.vscode/extensions.json:
--------------------------------------------------------------------------------
1 | {
2 | "recommendations": [
3 | "styled-components.vscode-styled-components",
4 | "golang.go"
5 | ]
6 | }
7 |
--------------------------------------------------------------------------------
/api/.gitignore:
--------------------------------------------------------------------------------
1 | node_modules
2 |
--------------------------------------------------------------------------------
/api/gnonativetypes/package.go:
--------------------------------------------------------------------------------
1 | package gnonativetypes
2 |
3 | import (
4 | "path"
5 |
6 | "github.com/gnolang/gno/tm2/pkg/amino"
7 | )
8 |
9 | var Package = amino.RegisterPackage(amino.NewPackage(
10 | "github.com/gnolang/gnonative/api/gnonativetypes",
11 | "land.gno.gnonative.v1",
12 | path.Join(amino.GetCallersDirname(), ".."),
13 | ).WithP3GoPkgPath("github.com/gnolang/gnonative/api/gen/go").
14 | WithDependencies().WithTypes(
15 | SetRemoteRequest{},
16 | SetRemoteResponse{},
17 | GetRemoteRequest{},
18 | GetRemoteResponse{},
19 | SetChainIDRequest{},
20 | SetChainIDResponse{},
21 | GetChainIDRequest{},
22 | GetChainIDResponse{},
23 | SetPasswordRequest{},
24 | SetPasswordResponse{},
25 | RotatePasswordRequest{},
26 | RotatePasswordResponse{},
27 | GenerateRecoveryPhraseRequest{},
28 | GenerateRecoveryPhraseResponse{},
29 | KeyInfo{},
30 | Coin{},
31 | BaseAccount{},
32 | ListKeyInfoRequest{},
33 | ListKeyInfoResponse{},
34 | HasKeyByNameRequest{},
35 | HasKeyByNameResponse{},
36 | HasKeyByAddressRequest{},
37 | HasKeyByAddressResponse{},
38 | HasKeyByNameOrAddressRequest{},
39 | HasKeyByNameOrAddressResponse{},
40 | GetKeyInfoByNameRequest{},
41 | GetKeyInfoByNameResponse{},
42 | GetKeyInfoByAddressRequest{},
43 | GetKeyInfoByAddressResponse{},
44 | GetKeyInfoByNameOrAddressRequest{},
45 | GetKeyInfoByNameOrAddressResponse{},
46 | CreateAccountRequest{},
47 | CreateAccountResponse{},
48 | ActivateAccountRequest{},
49 | ActivateAccountResponse{},
50 | GetActivatedAccountRequest{},
51 | GetActivatedAccountResponse{},
52 | QueryAccountRequest{},
53 | QueryAccountResponse{},
54 | DeleteAccountRequest{},
55 | DeleteAccountResponse{},
56 | QueryRequest{},
57 | QueryResponse{},
58 | RenderRequest{},
59 | RenderResponse{},
60 | QEvalRequest{},
61 | QEvalResponse{},
62 | MsgCall{},
63 | CallRequest{},
64 | CallResponse{},
65 | MsgSend{},
66 | SendRequest{},
67 | SendResponse{},
68 | MsgRun{},
69 | RunRequest{},
70 | RunResponse{},
71 | MakeTxResponse{},
72 | SignTxRequest{},
73 | SignTxResponse{},
74 | EstimateGasRequest{},
75 | EstimateGasResponse{},
76 | BroadcastTxCommitRequest{},
77 | BroadcastTxCommitResponse{},
78 | AddressToBech32Request{},
79 | AddressToBech32Response{},
80 | AddressFromBech32Request{},
81 | AddressFromBech32Response{},
82 | AddressFromMnemonicRequest{},
83 | AddressFromMnemonicResponse{},
84 | ValidateMnemonicWordRequest{},
85 | ValidateMnemonicWordResponse{},
86 | ValidateMnemonicPhraseRequest{},
87 | ValidateMnemonicPhraseResponse{},
88 | HelloRequest{},
89 | HelloResponse{},
90 | HelloStreamRequest{},
91 | HelloStreamResponse{},
92 | ).WithComments(path.Join(amino.GetCallersDirname(), "gnonativetypes.go")))
93 |
--------------------------------------------------------------------------------
/api/package-lock.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "version": "1.0.0",
4 | "lockfileVersion": 3,
5 | "requires": true,
6 | "packages": {
7 | "": {
8 | "name": "api",
9 | "version": "1.0.0",
10 | "license": "MIT",
11 | "dependencies": {
12 | "@babel/runtime": "^7.23.6",
13 | "@bufbuild/protobuf": "^1.7.2"
14 | }
15 | },
16 | "node_modules/@babel/runtime": {
17 | "version": "7.25.6",
18 | "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.25.6.tgz",
19 | "integrity": "sha512-VBj9MYyDb9tuLq7yzqjgzt6Q+IBQLrGZfdjOekyEirZPHxXWoTSGUTMrpsfi58Up73d13NfYLv8HT9vmznjzhQ==",
20 | "dependencies": {
21 | "regenerator-runtime": "^0.14.0"
22 | },
23 | "engines": {
24 | "node": ">=6.9.0"
25 | }
26 | },
27 | "node_modules/@bufbuild/protobuf": {
28 | "version": "1.10.0",
29 | "resolved": "https://registry.npmjs.org/@bufbuild/protobuf/-/protobuf-1.10.0.tgz",
30 | "integrity": "sha512-QDdVFLoN93Zjg36NoQPZfsVH9tZew7wKDKyV5qRdj8ntT4wQCOradQjRaTdwMhWUYsgKsvCINKKm87FdEk96Ag=="
31 | },
32 | "node_modules/regenerator-runtime": {
33 | "version": "0.14.1",
34 | "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.14.1.tgz",
35 | "integrity": "sha512-dYnhHh0nJoMfnkZs6GmmhFknAGRrLznOu5nc9ML+EJxGvrx6H7teuevqVqCuPcPK//3eDrrjQhehXVx9cnkGdw=="
36 | }
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/api/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "api",
3 | "version": "1.0.0",
4 | "main": "index.js",
5 | "license": "MIT",
6 | "dependencies": {
7 | "@babel/runtime": "^7.23.6",
8 | "@bufbuild/protobuf": "^1.7.2"
9 | }
10 | }
11 |
--------------------------------------------------------------------------------
/buf.gen.yaml:
--------------------------------------------------------------------------------
1 | version: v2
2 | plugins:
3 | - remote: buf.build/protocolbuffers/go
4 | out: ./api/gen/go
5 | opt: module=github.com/gnolang/gnonative/api/gen/go
6 | - remote: buf.build/connectrpc/go
7 | out: ./api/gen/go
8 | opt: module=github.com/gnolang/gnonative/api/gen/go
9 | - remote: buf.build/bufbuild/es:v2.2.5
10 | opt: target=ts
11 | out: ./api/gen/es
12 | - remote: buf.build/protocolbuffers/csharp
13 | out: ./api/gen/csharp
14 | - remote: buf.build/grpc/csharp
15 | out: ./api/gen/csharp
16 |
--------------------------------------------------------------------------------
/buf.yaml:
--------------------------------------------------------------------------------
1 | version: v2
2 | modules:
3 | - path: api
4 | name: buf.build/gnolang/gnonative
5 | lint:
6 | use:
7 | - DEFAULT
8 | except:
9 | - FIELD_NOT_REQUIRED
10 | - PACKAGE_NO_IMPORT_CYCLE
11 | disallow_comment_ignores: true
12 | breaking:
13 | use:
14 | - FILE
15 | except:
16 | - EXTENSION_NO_DELETE
17 | - FIELD_SAME_DEFAULT
18 |
--------------------------------------------------------------------------------
/docs/getting-started/create-new-app.md:
--------------------------------------------------------------------------------
1 | # Create a New App
2 |
3 | ## Overview
4 |
5 | This guide will walk you through creating a new Gno Native Kit App using the
6 | `new-app` command.
7 |
8 | ## Prerequisites
9 |
10 | Check the [Build instructions](../../README.md#build-instructions) guide for
11 | prerequisites.
12 |
13 | ## Create a new App
14 |
15 | To create a new app, run the following command in the repo folder:
16 |
17 | ```console
18 | cd $(go list -m -f '{{.Dir}}') # go to the root of the repo
19 | APP_NAME=MyApp make new-app
20 | ```
21 |
22 | This will create a new app in the `examples/js/react-native/MyApp` directory containing a basic
23 | integration with Gno.
24 |
25 | ## Run the App
26 |
27 | To run the app, run the following command:
28 |
29 | ```console
30 | cd examples/js/react-native/MyApp
31 | npx expo [run:android|run-ios]
32 | ```
33 |
34 | ## Using Gno in your App
35 |
36 | To use Gno in your app, you can import the `useGno` hook from
37 | `@gno/hooks/use-gno`:
38 |
39 | ```ts
40 | import { GnoNativeProvider, useGnoNativeContext } from '@gnolang/gnonative';
41 |
42 | const config = {
43 | remote: 'https://gno.berty.io',
44 | chain_id: 'dev',
45 | };
46 |
47 | export default function App() {
48 | return (
49 |
50 |
51 |
52 | );
53 | }
54 |
55 | const InnerApp = () => {
56 | const { gnonative } = useGnoNativeContext();
57 |
58 | useEffect(() => {
59 | (async () => {
60 | try {
61 | const remote = await gnonative.getRemote();
62 | const chainId = await gnonative.getChainID();
63 | console.log('Remote %s ChainId %s', remote, chainId);
64 | ...
65 | }
66 | ```
67 |
--------------------------------------------------------------------------------
/examples/go/goclient/README.md:
--------------------------------------------------------------------------------
1 | # A Go client
2 |
3 | This example shows how to implement a go client in few lines and make a request
4 | to the Gno blockchain. It calls the render function of the Boards realm.
5 |
6 | ## Run the server service
7 |
8 | Please read the corresponding
9 | [README](https://github.com/gnolang/gnonative/blob/main/goserver/README.md).
10 |
11 | ## Run the client
12 |
13 | In another terminal, execute the client.
14 |
15 | ### Unix Domain Socket
16 |
17 | The default path is `/tmp/socket`.
18 |
19 | `go run . uds` or specify the absolute socket path:
20 | `go run . uds -path /tmp/socket`
21 |
22 | ### TCP connection
23 |
24 | The default port is `26658`.
25 |
26 | `go run . tcp` or specify the remote address:
27 | `go run . tcp -addr http://localhost:26658`
28 |
29 | The client prints the raw Boards' messages.
30 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.eslintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": [
3 | "eslint:recommended",
4 | "plugin:react/recommended",
5 | "plugin:@typescript-eslint/recommended",
6 | "prettier",
7 | "plugin:storybook/recommended"
8 | ],
9 | "overrides": [],
10 | "parser": "@typescript-eslint/parser",
11 | "parserOptions": {
12 | "ecmaVersion": "latest",
13 | "sourceType": "module"
14 | },
15 | "plugins": ["react", "@typescript-eslint"],
16 | "rules": { "react/react-in-jsx-scope": "off" },
17 | "settings": {
18 | "react": {
19 | "version": "detect"
20 | },
21 | "import/resolver": {
22 | "typescript": {}
23 | }
24 | }
25 | }
26 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.gitignore:
--------------------------------------------------------------------------------
1 | # Learn more https://docs.github.com/en/get-started/getting-started-with-git/ignoring-files
2 |
3 | # native folders
4 | android/
5 | ios/
6 |
7 | # dependencies
8 | node_modules/
9 |
10 | # Expo
11 | .expo/
12 | dist/
13 | web-build/
14 |
15 | # Native
16 | *.orig.*
17 | *.jks
18 | *.p8
19 | *.p12
20 | *.key
21 | *.mobileprovision
22 |
23 | # Metro
24 | .metro-health-check*
25 |
26 | # debug
27 | npm-debug.*
28 | yarn-debug.*
29 | yarn-error.*
30 |
31 | # macOS
32 | .DS_Store
33 | *.pem
34 |
35 | # local env files
36 | .env*.local
37 |
38 | # typescript
39 | *.tsbuildinfo
40 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.prettierignore:
--------------------------------------------------------------------------------
1 | # Add files here to ignore them from prettier formatting
2 | build
3 | dist
4 | coverage
5 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.prettierrc:
--------------------------------------------------------------------------------
1 | {
2 | "semi": true,
3 | "tabWidth": 2,
4 | "printWidth": 140,
5 | "singleQuote": true,
6 | "trailingComma": "all",
7 | "jsxSingleQuote": true,
8 | "bracketSpacing": true,
9 | "useTabs": false
10 | }
11 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.storybook/index.js:
--------------------------------------------------------------------------------
1 | import { getStorybookUI } from '@storybook/react-native';
2 |
3 | import './storybook.requires';
4 |
5 | const StorybookUIRoot = getStorybookUI({});
6 |
7 | export default StorybookUIRoot;
8 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.storybook/main.js:
--------------------------------------------------------------------------------
1 | module.exports = {
2 | stories: ['./stories/**/*.stories.?(ts|tsx|js|jsx)'],
3 | addons: ['@storybook/addon-ondevice-controls', '@storybook/addon-ondevice-actions'],
4 | };
5 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.storybook/preview.js:
--------------------------------------------------------------------------------
1 | export const parameters = {
2 | controls: {
3 | matchers: {
4 | color: /(background|color)$/i,
5 | date: /Date$/,
6 | },
7 | },
8 | };
9 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.storybook/stories/Button/Button.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { TouchableOpacity, Text, StyleSheet } from 'react-native';
3 |
4 | export const MyButton = ({ onPress, text }) => {
5 | return (
6 |
7 | {text}
8 |
9 | );
10 | };
11 |
12 | const styles = StyleSheet.create({
13 | container: {
14 | paddingHorizontal: 16,
15 | paddingVertical: 8,
16 | backgroundColor: 'purple',
17 | borderRadius: 8,
18 | },
19 | text: { color: 'white' },
20 | });
21 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.storybook/stories/Button/Button.stories.js:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { View } from 'react-native';
3 | import { MyButton } from './Button';
4 |
5 | const MyButtonMeta = {
6 | title: 'MyButton',
7 | component: MyButton,
8 | argTypes: {
9 | onPress: { action: 'pressed the button' },
10 | },
11 | args: {
12 | text: 'Hello world',
13 | },
14 | decorators: [
15 | (Story) => (
16 |
17 |
18 |
19 | ),
20 | ],
21 | };
22 |
23 | export default MyButtonMeta;
24 |
25 | export const Basic = {};
26 |
27 | export const AnotherExample = {
28 | args: {
29 | text: 'Another example',
30 | },
31 | };
32 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/.storybook/storybook.requires.js:
--------------------------------------------------------------------------------
1 | /* do not change this file, it is auto generated by storybook. */
2 |
3 | import { configure, addDecorator, addParameters, addArgsEnhancer, clearDecorators } from '@storybook/react-native';
4 |
5 | global.STORIES = [
6 | {
7 | titlePrefix: '',
8 | directory: './.storybook/stories',
9 | files: '**/*.stories.?(ts|tsx|js|jsx)',
10 | importPathMatcher:
11 | '^\\.[\\\\/](?:\\.storybook\\/stories(?:\\/(?!\\.)(?:(?:(?!(?:^|\\/)\\.).)*?)\\/|\\/|$)(?!\\.)(?=.)[^/]*?\\.stories\\.(?:ts|tsx|js|jsx)?)$',
12 | },
13 | ];
14 |
15 | import '@storybook/addon-ondevice-controls/register';
16 | import '@storybook/addon-ondevice-actions/register';
17 |
18 | import { argsEnhancers } from '@storybook/addon-actions/dist/modern/preset/addArgs';
19 |
20 | import { decorators, parameters } from './preview';
21 |
22 | if (decorators) {
23 | if (__DEV__) {
24 | // stops the warning from showing on every HMR
25 | require('react-native').LogBox.ignoreLogs(['`clearDecorators` is deprecated and will be removed in Storybook 7.0']);
26 | }
27 | // workaround for global decorators getting infinitely applied on HMR, see https://github.com/storybookjs/react-native/issues/185
28 | clearDecorators();
29 | decorators.forEach((decorator) => addDecorator(decorator));
30 | }
31 |
32 | if (parameters) {
33 | addParameters(parameters);
34 | }
35 |
36 | try {
37 | argsEnhancers.forEach((enhancer) => addArgsEnhancer(enhancer));
38 | } catch {}
39 |
40 | const getStories = () => {
41 | return {
42 | './.storybook/stories/Button/Button.stories.js': require('./stories/Button/Button.stories.js'),
43 | '../src/components/alert/Alert.stories.tsx': require('../src/components/alert/Alert.stories.tsx'),
44 | '../src/components/buttons/Buttons.stories.tsx': require('../src/components/buttons/Buttons.stories.tsx'),
45 | '../src/components/textinput/Input.stories.tsx': require('../src/components/textinput/Input.stories.tsx'),
46 | '../src/components/account/AccountBalance.stories.tsx': require('../src/components/account/AccountBalance.stories.tsx'),
47 | '../src/components/account/CurrentAccount.stories.tsx': require('../src/components/account/CurrentAccount.stories.tsx'),
48 | '../src/components/modal/Modal.stories.tsx': require('../src/components/modal/Modal.stories.tsx'),
49 | '../src/components/modal/ModalConfirm.stories.tsx': require('../src/components/modal/ModalConfirm.stories.tsx'),
50 | '../src/components/change-network/ChangeNetwork.stories.tsx': require('../src/components/change-network/ChangeNetwork.stories.tsx'),
51 | };
52 | };
53 |
54 | configure(getStories, module, false);
55 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/App.tsx:
--------------------------------------------------------------------------------
1 | // order of imports is important
2 | import 'react-native-polyfill-globals/auto';
3 |
4 | import { GnoNativeProvider } from '@gnolang/gnonative';
5 | import { GnoboardProvider } from '@gno/provider/gnoboard-provider';
6 | import CustomRouter from '@gno/router/custom-router';
7 |
8 | // Polyfill async.Iterator. For some reason, the Babel presets and plugins are not doing the trick.
9 | // Code from here: https://www.typescriptlang.org/docs/handbook/release-notes/typescript-2-3.html#caveats
10 | (Symbol as any).asyncIterator = Symbol.asyncIterator || Symbol.for('Symbol.asyncIterator');
11 |
12 | function App() {
13 | const defaultConfig = {
14 | remote: 'gno.land:26657',
15 | chain_id: 'portal-loop',
16 | };
17 |
18 | return (
19 |
20 |
21 |
22 |
23 |
24 | );
25 | }
26 |
27 | const AppEntryPoint = App;
28 | // const AppEntryPoint = require('./.storybook').default;
29 |
30 | export default AppEntryPoint;
31 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/Makefile:
--------------------------------------------------------------------------------
1 | ANDROID_DEVICE ?=
2 |
3 | TEMPLATE_PROJECT := gnoboard
4 |
5 | check-program = $(foreach exec,$(1),$(if $(shell PATH="$(PATH)" which $(exec)),,$(error "Missing deps: no '$(exec)' in PATH")))
6 |
7 | PROJECT_DIR := $(shell go list -m -f '{{.Dir}}')
8 |
9 | ANDROID_FRAMEWORK_SRC_DIR := $(PROJECT_DIR)/framework/android
10 | ANDROID_FRAMEWORK_OUTPUT_DIR := android/libs
11 | ANDROID_FRAMEWORK_FILES := gnocore.aar gnocore-sources.jar
12 | ANDROID_FRAMEWORK_SRC := $(addprefix $(ANDROID_FRAMEWORK_SRC_DIR)/, $(ANDROID_FRAMEWORK_FILES))
13 | ANDROID_FRAMEWORK_DST := $(addprefix $(ANDROID_FRAMEWORK_OUTPUT_DIR)/, $(ANDROID_FRAMEWORK_FILES))
14 |
15 | IOS_FRAMEWORK_SRC_DIR := $(PROJECT_DIR)/framework/ios
16 | IOS_FRAMEWORK_OUTPUT_DIR := ios/Frameworks
17 | IOS_FRAMEWORK_FILES := GnoCore.xcframework
18 | IOS_FRAMEWORK_SRC := $(addprefix $(IOS_FRAMEWORK_SRC_DIR)/, $(IOS_FRAMEWORK_FILES))
19 | IOS_FRAMEWORK_DST := $(addprefix $(IOS_FRAMEWORK_OUTPUT_DIR)/, $(IOS_FRAMEWORK_FILES))
20 |
21 | # go files and dependencies
22 | go_framework_files := $(shell find $(PROJECT_DIR)/framework -iname '*.go')
23 | go_service_files := $(shell find $(PROJECT_DIR)/service -iname '*.go')
24 | go_files := $(go_framework_files) $(go_service_files)
25 | go_deps := $(PROJECT_DIR)/go.mod $(PROJECT_DIR)/go.sum $(go_files)
26 |
27 | ts_check:
28 | npm run ts:check
29 |
30 | # - Node: Handle node_modules
31 |
32 | node_modules: package.json package-lock.json
33 | $(call check-program, npm)
34 | (npm install && touch $@) || true
35 | .PHONY: node_modules
36 |
37 | ######### ANDROID #########
38 |
39 | android: node_modules ts_check $(ANDROID_FRAMEWORK_SRC)
40 | $(call check-program, npx)
41 | npx expo run:android
42 | .PHONY: build.android
43 |
44 | $(ANDROID_FRAMEWORK_SRC): $(go_deps)
45 | cd $(PROJECT_DIR); $(MAKE) framework.android
46 |
47 | ######### IOS #########
48 |
49 | ios: node_modules ts_check $(IOS_FRAMEWORK_SRC)
50 | $(call check-program, npx)
51 | npx expo run:ios
52 | .PHONY: build.ios
53 |
54 | $(IOS_FRAMEWORK_SRC): $(go_deps)
55 | cd $(PROJECT_DIR); $(MAKE) framework.ios
56 |
57 | # - Helpers
58 |
59 | android.reverse_tcp:
60 | $(call check-program, adb)
61 | $(if $(ANDROID_DEVICE),,$(eval ANDROID_DEVICE = $(shell adb devices | tail +2 | head -1 | cut -f 1)))
62 | @if [ -z "$(ANDROID_DEVICE)" ]; then \
63 | >&2 echo "ERROR: no Android device found"; exit 1; \
64 | fi
65 | adb -s $(ANDROID_DEVICE) reverse tcp:8081 tcp:8081 # metro
66 | adb -s $(ANDROID_DEVICE) reverse tcp:36657 tcp:36657 # gnodev
67 | .PHONY: android.reverse_tcp
68 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/README.md:
--------------------------------------------------------------------------------
1 | # gnoboard Mobile APP
2 |
3 | ## Requirements
4 |
5 | The gnoboard mobile app uses Expo. You can review the general expo requirements:
6 |
7 | - Expo Requirements: https://docs.expo.dev/get-started/installation/
8 |
9 | Please also follow the instructions in the Gno Native Kit's [README](https://github.com/gnolang/gnonative/blob/main/README.md) to install the requirements on your platform.
10 |
11 | ## Build the app
12 |
13 | ```bash
14 | make android
15 | # or
16 | make ios
17 | ```
18 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "expo": {
3 | "name": "gnoboard",
4 | "version": "1.0.0",
5 | "slug": "gnoboard",
6 | "orientation": "portrait",
7 | "icon": "./assets/icon.png",
8 | "userInterfaceStyle": "light",
9 | "splash": {
10 | "image": "./assets/splash.png",
11 | "resizeMode": "contain",
12 | "backgroundColor": "#121212"
13 | },
14 | "ios": {
15 | "supportsTablet": true,
16 | "bundleIdentifier": "land.gno.gnoboard"
17 | },
18 | "android": {
19 | "adaptiveIcon": {
20 | "foregroundImage": "./assets/adaptive-icon.png",
21 | "backgroundColor": "#121212"
22 | },
23 | "package": "land.gno.gnoboard"
24 | },
25 | "web": {
26 | "favicon": "./assets/favicon.png"
27 | }
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/assets/adaptive-icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnolang/gnonative/4cda63b0145f530e3fac0158f6f3986285ae992d/examples/js/expo/gnoboard/assets/adaptive-icon.png
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/assets/favicon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnolang/gnonative/4cda63b0145f530e3fac0158f6f3986285ae992d/examples/js/expo/gnoboard/assets/favicon.png
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/assets/icon.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnolang/gnonative/4cda63b0145f530e3fac0158f6f3986285ae992d/examples/js/expo/gnoboard/assets/icon.png
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/assets/splash.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/gnolang/gnonative/4cda63b0145f530e3fac0158f6f3986285ae992d/examples/js/expo/gnoboard/assets/splash.png
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/babel.config.js:
--------------------------------------------------------------------------------
1 | module.exports = function (api) {
2 | api.cache(true);
3 | return {
4 | presets: ['babel-preset-expo'],
5 | plugins: [
6 | [
7 | 'module-resolver',
8 | {
9 | root: ['./src'],
10 | extensions: ['.ios.js', '.android.js', '.js', '.ts', '.tsx', '.json'],
11 | alias: {
12 | '@gno': './src/',
13 | },
14 | },
15 | ],
16 | ],
17 | };
18 | };
19 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/metro.config.js:
--------------------------------------------------------------------------------
1 | // Learn more https://docs.expo.io/guides/customizing-metro
2 | const { getDefaultConfig } = require('expo/metro-config');
3 | const { mergeConfig } = require('metro-config');
4 | const path = require('path');
5 |
6 | /** @type {import('expo/metro-config').MetroConfig} */
7 | // const config = getDefaultConfig(__dirname);
8 | //
9 | // module.exports = config;
10 | const config = {};
11 |
12 | module.exports = mergeConfig(getDefaultConfig(__dirname), config);
13 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "gnoboard",
3 | "version": "1.0.0",
4 | "main": "node_modules/expo/AppEntry.js",
5 | "scripts": {
6 | "start": "expo start -d",
7 | "android": "npx react-native run-android",
8 | "ios": "npx react-native run-ios",
9 | "web": "expo start --web",
10 | "lint": "eslint src/**/*.{ts,tsx}",
11 | "lint:fix": "eslint --fix 'src/**/*.{js,jsx,ts,tsx,json}'",
12 | "format": "prettier --write 'src/**/*.{js,jsx,ts,tsx,css,md,json}' --config ./.prettierrc",
13 | "storybook-generate": "sb-rn-get-stories",
14 | "ts:check": "tsc",
15 | "storybook-watch": "sb-rn-watcher"
16 | },
17 | "dependencies": {
18 | "@bufbuild/protobuf": "^1.7.2",
19 | "@connectrpc/connect": "^1.4.0",
20 | "@connectrpc/connect-web": "^1.4.0",
21 | "@gnolang/gnonative": "^3.0.2",
22 | "@react-navigation/bottom-tabs": "^6.5.8",
23 | "@react-navigation/native": "^6.1.7",
24 | "@react-navigation/native-stack": "^6.9.13",
25 | "base-64": "^1.0.0",
26 | "buffer": "^6.0.3",
27 | "expo": "^51.0.31",
28 | "expo-splash-screen": "~0.27.5",
29 | "expo-status-bar": "~1.12.1",
30 | "react": "18.2.0",
31 | "react-native": "0.74.5",
32 | "react-native-fetch-api": "^3.0.0",
33 | "react-native-get-random-values": "^1.9.0",
34 | "react-native-marked": "^6.0.3",
35 | "react-native-polyfill-globals": "^3.1.0",
36 | "react-native-safe-area-context": "^4.7.2",
37 | "react-native-screens": "3.31.1",
38 | "react-native-svg": "13.14.0",
39 | "react-native-url-polyfill": "^2.0.0",
40 | "styled-components": "^6.0.8",
41 | "text-encoding": "^0.7.0",
42 | "web-streams-polyfill": "^3.2.1"
43 | },
44 | "devDependencies": {
45 | "@babel/core": "^7.20.0",
46 | "@react-native-async-storage/async-storage": "1.23.1",
47 | "@react-native-community/datetimepicker": "8.0.1",
48 | "@react-native-community/slider": "^4.4.3",
49 | "@storybook/addon-actions": "^6.5.16",
50 | "@storybook/addon-controls": "^6.5.16",
51 | "@storybook/addon-ondevice-actions": "^6.5.6",
52 | "@storybook/addon-ondevice-controls": "^6.5.6",
53 | "@storybook/react-native": "^6.5.6",
54 | "@tsconfig/react-native": "^3.0.2",
55 | "@types/jest": "^29.5.3",
56 | "@types/react": "^18.2.20",
57 | "@types/react-native": "^0.72.3",
58 | "@types/react-test-renderer": "^18.0.0",
59 | "@typescript-eslint/eslint-plugin": "^6.7.2",
60 | "@typescript-eslint/parser": "^6.7.2",
61 | "babel-loader": "^8.3.0",
62 | "babel-plugin-module-resolver": "^5.0.0",
63 | "eslint": "^8.49.0",
64 | "eslint-config-prettier": "^9.0.0",
65 | "eslint-import-resolver-typescript": "^3.6.0",
66 | "eslint-plugin-import": "^2.28.1",
67 | "eslint-plugin-prettier": "^5.0.0",
68 | "eslint-plugin-react": "^7.33.2",
69 | "eslint-plugin-react-hooks": "^4.6.0",
70 | "eslint-plugin-storybook": "^0.6.14",
71 | "lint-staged": "^14.0.1",
72 | "prettier": "3.0.3",
73 | "react-dom": "18.2.0",
74 | "typescript": "~5.3.3"
75 | },
76 | "private": true
77 | }
78 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/account/AccountBalance.stories.tsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 | import React from 'react';
3 | import AccountBalance, { Props } from './AccountBalance';
4 |
5 | export default {
6 | title: 'AccountBalance',
7 | component: AccountBalance,
8 | decorators: [
9 | (Story: React.FC) => (
10 |
11 |
12 |
13 | ),
14 | ],
15 | args: {
16 | accountInfo: {
17 | coins: [
18 | { denom: 'GNOT', amount: '0.0002324' },
19 | { denom: 'GNO', amount: '0.0002324' },
20 | { denom: 'BTC', amount: '0.0302324112' },
21 | ],
22 | },
23 | },
24 | };
25 |
26 | export const Basic = (props: Props) => {
27 | return ;
28 | };
29 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/account/AccountBalance.tsx:
--------------------------------------------------------------------------------
1 | import Text from '../texts';
2 | import styled from 'styled-components/native';
3 | import { colors } from '@gno/styles';
4 | import { BaseAccount } from '@gnolang/gnonative';
5 | import Row from '../row';
6 |
7 | export type Props = {
8 | accountInfo: BaseAccount | undefined;
9 | unknownAddress: boolean;
10 | };
11 |
12 | const AccountBalance = (props: Props) => {
13 | if (props.unknownAddress) {
14 | return (
15 |
16 |
17 | Your account is not known on the blockchain.
18 |
19 |
20 | );
21 | }
22 |
23 | if (!props.accountInfo) {
24 | return null;
25 | }
26 |
27 | const coins = props.accountInfo.coins;
28 |
29 | return (
30 |
31 | {coins.map((coin, index) => (
32 |
33 | ))}
34 |
35 | );
36 | };
37 |
38 | const Coin = (props: { amount: bigint; denom: string }) => {
39 | return (
40 |
41 | {props.denom}
42 | {props.amount.toString()}
43 |
44 | );
45 | };
46 |
47 | const CenterView = styled.View`
48 | background-color: ${colors.grayscale['200']};
49 | padding: 8px 8px 16px 8px;
50 | border-radius: 8px;
51 | border: 1px solid ${colors.grayscale['700']};
52 | justify-content: center;
53 | align-items: center;
54 | `;
55 |
56 | export default AccountBalance;
57 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/account/CurrentAccount.stories.tsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 | import React from 'react';
3 | import CurrentAccount, { Props } from './CurrentAccoutn';
4 |
5 | export default {
6 | title: 'CurrentAccount',
7 | component: CurrentAccount,
8 | decorators: [
9 | (Story: React.FC) => (
10 |
11 |
12 |
13 | ),
14 | ],
15 | args: {
16 | account: {
17 | name: 'Account 1',
18 | }
19 | },
20 | };
21 |
22 | export const Basic = (props: Props) => {
23 | return ;
24 | };
25 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/account/CurrentAccoutn.tsx:
--------------------------------------------------------------------------------
1 | import Text from '../texts';
2 | import { KeyInfo } from '@gnolang/gnonative';
3 | import styled from 'styled-components/native';
4 |
5 | export type Props = {
6 | account: KeyInfo | undefined;
7 | };
8 |
9 | const CurrentAccount = ({ account }: Props) => {
10 | if (!account)
11 | return (
12 |
13 | No Account Selected
14 |
15 | );
16 |
17 | return (
18 |
19 | {account.name}
20 |
21 | );
22 | };
23 |
24 | const CenterView = styled.View`
25 | align-items: center;
26 | margin-top: 16px;
27 | margin-bottom: 16px;
28 | `;
29 |
30 | export default CurrentAccount;
31 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/account/index.tsx:
--------------------------------------------------------------------------------
1 | import AccountBalance from './AccountBalance';
2 |
3 | export { AccountBalance };
4 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/alert/Alert.stories.tsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 | import Alert, { Props } from '.';
3 | import React from 'react';
4 |
5 | export default {
6 | title: 'Alert',
7 | component: Alert,
8 | decorators: [
9 | (Story: React.FC) => (
10 |
11 |
12 |
13 | ),
14 | ],
15 | args: {
16 | message: 'Here goes an error.',
17 | severity: 'error',
18 | },
19 | };
20 |
21 | export const Basic = ({ message = 'Here goes an error.', severity = 'error' }: Props) => {
22 | return ;
23 | };
24 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/alert/index.tsx:
--------------------------------------------------------------------------------
1 | import styled from 'styled-components/native';
2 | import { colors } from '@gno/styles';
3 | import Exclamation from '../icons/Exclamation';
4 |
5 | export interface Props {
6 | message?: string;
7 | severity: 'error' | 'warning' | 'info' | 'success';
8 | }
9 |
10 | const Wrapper = styled.View`
11 | justify-content: center;
12 | align-items: center;
13 | `;
14 |
15 | const InnerContent = styled.View<{ severity: Props['severity'] }>`
16 | flex-direction: row;
17 | align-items: center;
18 | border-radius: 16px;
19 | padding-left: 12px;
20 | padding-right: 12px;
21 | background-color: ${({ severity }) => {
22 | switch (severity) {
23 | case 'error':
24 | return colors.danger;
25 | case 'warning':
26 | return colors.warning;
27 | case 'info':
28 | return colors.main;
29 | case 'success':
30 | return colors.success;
31 | }
32 | }};
33 | `;
34 |
35 | const ErrorText = styled.Text<{ paddingLeft: boolean }>`
36 | padding: 10px;
37 | font-size: 14px;
38 | font-weight: 500;
39 | line-height: 20px;
40 | letter-spacing: 0;
41 | padding-left: ${(props) => (props.paddingLeft ? '5.5px' : '4.5px')};
42 | text-align: center;
43 | `;
44 |
45 | const Alert = ({ message, severity }: Props) => {
46 | const isError = severity === 'error';
47 |
48 | return (
49 |
50 | {message ? (
51 |
52 | {isError && }
53 | {message}
54 |
55 | ) : null}
56 |
57 | );
58 | };
59 |
60 | export default Alert;
61 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/buttons/Buttons.stories.tsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 | import React from 'react';
3 | import Button, { Props } from '.';
4 |
5 | export default {
6 | title: 'Button',
7 | component: Button,
8 | decorators: [
9 | (Story: React.FC) => (
10 |
11 |
12 |
13 | ),
14 | ],
15 | args: {
16 | title: 'Button label',
17 | },
18 | };
19 |
20 | export const Basic = (props: Props) => {
21 | return ;
22 | };
23 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/buttons/index.tsx:
--------------------------------------------------------------------------------
1 | import React from 'react';
2 | import { ActivityIndicator, TouchableOpacityProps } from 'react-native';
3 | import { StyleSheet } from 'react-native';
4 | import { colors } from '@gno/styles/colors';
5 | import styled from 'styled-components/native';
6 | import Text from '../texts';
7 |
8 | type ButtonVariant = 'primary' | 'secondary' | 'tertiary' | 'white' | 'primary2' | 'primary-red' | 'secondary-red';
9 |
10 | export type Props = {
11 | title: string;
12 | onPress: () => void;
13 | loading?: boolean;
14 | variant: ButtonVariant;
15 | } & TouchableOpacityProps;
16 |
17 | const Button: React.FC = ({ title, onPress, loading = false, variant, ...rest }) => {
18 | return (
19 |
20 | {loading ? : {title}}
21 |
22 | );
23 | };
24 |
25 | const TouchableOpacityButton = styled.TouchableOpacity<{ variant: ButtonVariant }>`
26 | background-color: ${(props) => getStyle(props.variant)};
27 | width: 100%;
28 | height: 48px;
29 | justify-content: center;
30 | border-radius: 28px;
31 | `;
32 |
33 | const getStyle = (variant: ButtonVariant) => {
34 | switch (variant) {
35 | case 'primary':
36 | return colors.primary;
37 | case 'secondary':
38 | return colors.button.secondary;
39 | case 'tertiary':
40 | return colors.tertiary;
41 | case 'white':
42 | return colors.white;
43 | case 'primary2':
44 | return 'transparent';
45 | case 'primary-red':
46 | return colors.red[500];
47 | case 'secondary-red':
48 | return colors.red[300];
49 | default:
50 | return colors.blue;
51 | }
52 | };
53 |
54 | const styles = StyleSheet.create({
55 | buttonText: {
56 | color: colors.white,
57 | fontWeight: 'bold',
58 | textAlign: 'center',
59 | },
60 | });
61 |
62 | export default Button;
63 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/change-network/ChangeNetwork.stories.tsx:
--------------------------------------------------------------------------------
1 | import { View } from 'react-native';
2 | import NetworkListItem, { Props } from './network-list-item';
3 | import { Spacer } from '../row';
4 | import NetworkList from './network-list';
5 | import chains from '@gno/resources/chains/chains.json';
6 |
7 | export default {
8 | title: 'ChangNetwork',
9 | component: NetworkListItem,
10 | decorators: [
11 | (Story: React.FC) => (
12 |
13 |
14 |
15 | ),
16 | ],
17 | args: {
18 | networkMetainfo: {
19 | networkName: 'test3',
20 | gnoAddress: 'https://test3.gno.land',
21 | },
22 | },
23 | };
24 |
25 | export const Basic = () => {
26 | // This callback isn't used by the storybook
27 | const onNetworkChange = async () => {}
28 | return (
29 | <>
30 |
31 | >
32 | );
33 | };
34 |
35 | export const ListItem = ({ networkMetainfo }: Props) => {
36 | // This callback isn't used by the storybook
37 | const onPress = async () => {}
38 | return (
39 | <>
40 |
41 |
42 |
43 |
44 | >
45 | );
46 | };
47 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/change-network/network-list-item/index.tsx:
--------------------------------------------------------------------------------
1 | import Icons from '@gno/components/icons';
2 | import Text from '@gno/components/texts';
3 | import { NetworkMetainfo } from '@gno/types';
4 | import { colors } from '@gno/styles';
5 | import styled from 'styled-components/native';
6 |
7 | export interface Props {
8 | currentChainId: string | undefined;
9 | networkMetainfo: NetworkMetainfo;
10 | onPress: (item: NetworkMetainfo) => void;
11 | }
12 |
13 | const NetworkListItem: React.FC = ({ networkMetainfo, currentChainId, onPress }: Props) => (
14 | onPress(networkMetainfo)}>
15 |
16 | {networkMetainfo.chainName}
17 | {networkMetainfo.gnoAddress}
18 |
19 |
20 | {currentChainId === networkMetainfo.chainId && }
21 |
22 | );
23 |
24 | const InUse = () => (
25 | <>
26 |
27 | in use
28 | >
29 | );
30 |
31 | const Row = styled.TouchableOpacity`
32 | display: flex;
33 | flex-direction: row;
34 | justify-content: space-between;
35 | align-items: center;
36 | background-color: ${colors.button.primary};
37 | height: auto;
38 | padding: 9px 16px;
39 | border-radius: 18px;
40 | transition: 0.2s;
41 | `;
42 |
43 | const LeftItens = styled.View`
44 | display: flex;
45 | flex-direction: column;
46 | align-items: flex-start;
47 | `;
48 |
49 | const RightItens = styled.View`
50 | display: flex;
51 | flex-direction: row;
52 | align-items: center;
53 | `;
54 |
55 | export default NetworkListItem;
56 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/change-network/network-list/index.tsx:
--------------------------------------------------------------------------------
1 | import { NetworkMetainfo } from '@gno/types';
2 | import NetworkListItem from '../network-list-item';
3 | import Text from '@gno/components/texts';
4 | import styled from 'styled-components/native';
5 |
6 | interface Props {
7 | currentChainId: string | undefined;
8 | networkMetainfos: NetworkMetainfo[];
9 | onNetworkChange: (networkMetainfo: NetworkMetainfo) => void;
10 | }
11 |
12 | const NetworkList: React.FC = ({ currentChainId, networkMetainfos = [], onNetworkChange }: Props) => {
13 | if (networkMetainfos.length === 0) {
14 | return No network found.;
15 | }
16 |
17 | return (
18 |
19 | {networkMetainfos.map((networkMetainfo, idx) => (
20 | onNetworkChange(item)}
25 | />
26 | ))}
27 |
28 | );
29 | };
30 |
31 | const NetworkListWrapper = styled.View`
32 | margin-top: 16px;
33 | `;
34 |
35 | export default NetworkList;
36 |
--------------------------------------------------------------------------------
/examples/js/expo/gnoboard/src/components/common/side-menu-account-item/side-menu-account-item.tsx:
--------------------------------------------------------------------------------
1 | import Button from '@gno/components/buttons';
2 | import { Spacer } from '@gno/components/row';
3 | import { KeyInfo } from '@gnolang/gnonative';
4 |
5 | interface SideMenuAccountItemProps {
6 | account: KeyInfo;
7 | changeAccount: (account: KeyInfo) => void;
8 | }
9 |
10 | const SideMenuAccountItem = (props: SideMenuAccountItemProps) => {
11 | const { account, changeAccount } = props;
12 | return (
13 | <>
14 |
15 |