Skip to content
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
5 changes: 5 additions & 0 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
"bn-sdk": "github:blocknative/bn-sdk#master",
"bowser": "^2.5.2",
"ow": "^0.13.2",
"promise-cancelable": "^2.1.1",
"rollup-plugin-node-globals": "^1.4.0",
"svelte": "^3.0.0",
"svelte-i18n": "^1.1.2-beta"
Expand Down
3 changes: 2 additions & 1 deletion rollup.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,8 @@ export default [
"svelte",
"svelte/store",
"svelte/internal",
"svelte/transition"
"svelte/transition",
"promise-cancelable"
],
plugins: [
svelte(),
Expand Down
16 changes: 9 additions & 7 deletions src/index.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import blocknativeApi from "bn-sdk"
import Onboard from "./views/Onboard.svelte"
import { app, address, network, balance, provider } from "./stores"
import { selectWallet, prepareWallet, config, getState } from "./api"
import { validateInit } from "./validation"
import { getUserAgent } from "./utilities"
import { initializeBlocknative } from "./services"

function init(initialization) {
getUserAgent()
Expand All @@ -12,19 +12,21 @@ function init(initialization) {

const { subscriptions, ...rest } = initialization

const blocknative = initializeBlocknative(
initialization.dappId,
initialization.networkId
)

app.update(store => ({
...store,
...rest,
blocknative: new blocknativeApi({
dappId: initialization.dappId,
networkId: initialization.networkId
})
...rest
}))

new Onboard({
target: document.body,
props: {
onboardingModules: initialization.modules.prepareWallet
onboardingModules: initialization.modules.prepareWallet,
blocknative
}
})

Expand Down
16 changes: 16 additions & 0 deletions src/services.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
import blocknativeApi from "bn-sdk"

let blocknative

export function initializeBlocknative(dappId, networkId) {
blocknative = blocknativeApi({
dappId,
networkId
})

return blocknative
}

export function getBlocknative() {
return blocknative
}
109 changes: 106 additions & 3 deletions src/stores.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
import { writable } from "svelte/store"
import Cancelable from "promise-cancelable"
import { validateWalletInterface } from "./validation"
import { getBlocknative } from "./services"

export const app = writable({
dappId: null,
Expand All @@ -9,18 +11,22 @@ export const app = writable({
selectWalletCompleted: false,
prepareWallet: false,
prepareWalletCompleted: false,
modules: null
modules: null,
blocknative: null
})

export const configuration = writable({
darkMode: false
})

export let syncingState = false
export const balanceSyncStatus = {
syncing: false,
error: false
}

export const address = createUserStateStore("address")
export const network = createUserStateStore("network")
export const balance = createUserStateStore("balance")
export const balance = createBalanceStore()
export const provider = writable(null)

export const state = createState({
Expand Down Expand Up @@ -128,3 +134,100 @@ function createUserStateStore(parameter) {
}
}
}

function createBalanceStore() {
let stateSyncer
let emitter

const { subscribe } = derived(
[address, network],
([$address, $network], set) => {
if (stateSyncer) {
syncState(stateSyncer.get, set)

emitter = getBlocknative().account($address)

emitter.on("txConfirmed", () => {
syncState(stateSyncer.get, set)
})
}
}
)

return {
subscribe,
setStateSyncer: syncer => {
if (!syncer || typeof syncer !== "object") {
throw new Error("setStateSyncer must be called with a valid interface")
}

stateSyncer = syncer
}
}
}

function syncState(func, set) {
const prom = makeQuerablePromise(
new Cancelable((resolve, reject, onCancel) => {
console.log("calling stateSyncer for:", parameter)
func()
.then(resolve)
.catch(reject)

onCancel(resolve)
})
)

balanceSyncStatus.syncing = prom

prom
.then(result => {
set(result)
balanceSyncStatus.syncing = false
})
.catch(err => {
throw new Error(`Error getting balance from state syncer: ${err}`)
})

const timedOut = wait(1000)

timedOut.then(() => {
if (!prom.isFulfilled()) {
console.log("promise timed out")
prom.cancel()

balanceSyncStatus.syncing = false
balanceSyncStatus.error = `There was a problem getting the ${parameter} of this wallet`
}
})
}

function wait(time) {
return new Promise(resolve => setTimeout(resolve, time))
}

function makeQuerablePromise(promise) {
let isResolved = false
let isRejected = false

const result = promise.then(
function(v) {
isResolved = true
return v
},
function(e) {
isRejected = true
throw e
}
)
result.isFulfilled = function() {
return isResolved || isRejected
}
result.isResolved = function() {
return isResolved
}
result.isRejected = function() {
return isRejected
}
return result
}
3 changes: 2 additions & 1 deletion src/views/Onboard.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
import { app } from "../stores";

export let onboardingModules;
export let blocknative;
</script>

<style>
Expand Down Expand Up @@ -32,5 +33,5 @@
{/if}

{#if $app.prepareWallet}
<PrepareWallet modules={onboardingModules} />
<PrepareWallet modules={onboardingModules} {blocknative} />
{/if}
7 changes: 4 additions & 3 deletions src/views/PrepareWallet.svelte
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import { validateModal } from "../validation";

export let modules;
export let blocknative;

let activeModal;
let currentModule;
Expand Down Expand Up @@ -99,9 +100,9 @@
function runModules(modules) {
return new Promise(async resolve => {
for (const module of modules) {
if (syncingState) {
await syncingState;
}
console.log("Syncing state");
await Promise.all(Object.values(syncingState));
console.log("finished syncing state");

const isInvalid = await invalidState(module, state.get());

Expand Down