@wirexapp/card-wallet-topup-web 1.1.0-beta.0 → 1.1.0-beta.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +32 -0
- package/README.md +1 -2
- package/dist/index.d.ts +20 -0
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +69 -1
- package/dist/index.js.map +1 -1
- package/dist/walletPopup.d.ts.map +1 -1
- package/dist/walletPopup.js +18 -3
- package/dist/walletPopup.js.map +1 -1
- package/package.json +2 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @wirexapp/card-wallet-topup-web
|
|
2
2
|
|
|
3
|
+
## 1.1.0-beta.2
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 1d89a12: Wallet polish: `checkWalletAvailability` gains a persistent
|
|
8
|
+
stale-while-revalidate `cache` option (Storage-shaped adapter,
|
|
9
|
+
localStorage by default, `null` to disable); the checkout popup centers
|
|
10
|
+
over the opener window; the payment-sheet's billing contact, cardholder
|
|
11
|
+
name and Apple transaction id ride the token payload as optional fields
|
|
12
|
+
(collected only when the provider config requests billing).
|
|
13
|
+
|
|
14
|
+
### Patch Changes
|
|
15
|
+
|
|
16
|
+
- Updated dependencies [1d89a12]
|
|
17
|
+
- @wirexapp/card-sdk-core@1.1.0-beta.2
|
|
18
|
+
|
|
19
|
+
## 1.1.0-beta.1
|
|
20
|
+
|
|
21
|
+
### Minor Changes
|
|
22
|
+
|
|
23
|
+
- Wallet checkout polish: loading skeleton + popup page padding; the popup
|
|
24
|
+
carries `appearance` in the URL fragment so the pre-quote skeleton renders
|
|
25
|
+
themed; privacy-only legal line with a partner-configurable
|
|
26
|
+
`branding.privacyUrl` (https-only, validated in-frame, Wirex policy
|
|
27
|
+
fallback); Google Pay button draws the design pill radius natively; fee row
|
|
28
|
+
rounds up to the minor unit (host-app parity).
|
|
29
|
+
|
|
30
|
+
### Patch Changes
|
|
31
|
+
|
|
32
|
+
- Updated dependencies
|
|
33
|
+
- @wirexapp/card-sdk-core@1.1.0-beta.1
|
|
34
|
+
|
|
3
35
|
## 0.1.0-beta.4
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -21,5 +21,4 @@ can tokenize (Safari → Apple Pay, Android Chrome → Google Pay), and only whe
|
|
|
21
21
|
the `WalletTopup` capability is Active.
|
|
22
22
|
|
|
23
23
|
React bindings: `useWalletAvailability()` + `<WalletTopUpForm />` in
|
|
24
|
-
`@wirexapp/card-react`. Full partner docs:
|
|
25
|
-
(packages → card-wallet-topup-web).
|
|
24
|
+
`@wirexapp/card-react`. Full partner docs: the Wirex Card SDK partner documentation site (page “card-wallet-topup-web”) — the link is shared by your Wirex integration contact.
|
package/dist/index.d.ts
CHANGED
|
@@ -25,17 +25,37 @@ export type { PciWalletPaymentToken } from './walletElement.js';
|
|
|
25
25
|
/** Config of the combined (review + buttons) wallet checkout element. */
|
|
26
26
|
export type WalletTopUpFormConfig = PciWalletTopUpElementConfig;
|
|
27
27
|
export type WalletTopUpForm = PciWalletTopUpElement;
|
|
28
|
+
/**
|
|
29
|
+
* Web-Storage-SHAPED persistence adapter for the probe answer —
|
|
30
|
+
* `window.localStorage` / `window.sessionStorage` are directly assignable,
|
|
31
|
+
* and any object with the same two methods qualifies (the JSON payload is
|
|
32
|
+
* owned by the SDK, the adapter only stores strings).
|
|
33
|
+
*/
|
|
34
|
+
export interface PciAvailabilityCacheStorage {
|
|
35
|
+
getItem(key: string): string | null;
|
|
36
|
+
setItem(key: string, value: string): void;
|
|
37
|
+
}
|
|
28
38
|
export interface CheckWalletAvailabilityOptions {
|
|
29
39
|
force?: boolean;
|
|
30
40
|
/** The app config's `topup` provider block (`default_provider` entry —
|
|
31
41
|
* before a quote exists there is nothing to echo). When present its Google
|
|
32
42
|
* Pay values drive the readiness check verbatim. */
|
|
33
43
|
config?: PciWalletProviderConfig;
|
|
44
|
+
/** Persistent stale-while-revalidate cache of the LAST REAL probe answer:
|
|
45
|
+
* a fresh page load resolves instantly from it while the live probe keeps
|
|
46
|
+
* running and refreshes it (probe failures never overwrite it). DEFAULT:
|
|
47
|
+
* `window.localStorage`. Pass any Storage-shaped adapter
|
|
48
|
+
* (`sessionStorage` qualifies) — or `null` to disable persistence. */
|
|
49
|
+
cache?: PciAvailabilityCacheStorage | null;
|
|
34
50
|
}
|
|
35
51
|
/**
|
|
36
52
|
* Phase-A availability check. Run it before showing the wallet row at all —
|
|
37
53
|
* `false` means hide the row (`googlePay: false` on desktop/non-Chrome is
|
|
38
54
|
* expected: the cryptogram-only policy has no eligible cards there).
|
|
55
|
+
*
|
|
56
|
+
* Resolution order: in-memory (per page session) → the persistent cache
|
|
57
|
+
* (instant answer + background revalidation) → the live probe. `force: true`
|
|
58
|
+
* skips both caches and awaits a fresh probe.
|
|
39
59
|
*/
|
|
40
60
|
export declare const checkWalletAvailability: (sdk: PciSdkConfig, options?: CheckWalletAvailabilityOptions) => Promise<PciWalletAvailability>;
|
|
41
61
|
/** Combined variant: review screen + wallet buttons in one Wirex-served frame. */
|
package/dist/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,2BAA2B,EACjC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AAMvB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,GACrB,CAAC;AACF,YAAY,EACV,2BAA2B,EAC3B,mBAAmB,EACnB,yBAAyB,GAC1B,CAAC;AACF,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,yEAAyE;AACzE,MAAM,MAAM,qBAAqB,GAAG,2BAA2B,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG,qBAAqB,CAAC;AASpD,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;yDAEqD;IACrD,MAAM,CAAC,EAAE,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EAEL,KAAK,YAAY,EACjB,KAAK,qBAAqB,EAC1B,KAAK,uBAAuB,EAC7B,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,KAAK,2BAA2B,EACjC,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,EACpB,KAAK,mBAAmB,EACxB,KAAK,yBAAyB,EAC/B,MAAM,eAAe,CAAC;AAMvB,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,GACrB,CAAC;AACF,YAAY,EACV,2BAA2B,EAC3B,mBAAmB,EACnB,yBAAyB,GAC1B,CAAC;AACF,YAAY,EAAE,qBAAqB,EAAE,MAAM,iBAAiB,CAAC;AAE7D,yEAAyE;AACzE,MAAM,MAAM,qBAAqB,GAAG,2BAA2B,CAAC;AAChE,MAAM,MAAM,eAAe,GAAG,qBAAqB,CAAC;AASpD;;;;;GAKG;AACH,MAAM,WAAW,2BAA2B;IAC1C,OAAO,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACpC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3C;AAED,MAAM,WAAW,8BAA8B;IAC7C,KAAK,CAAC,EAAE,OAAO,CAAC;IAChB;;yDAEqD;IACrD,MAAM,CAAC,EAAE,uBAAuB,CAAC;IACjC;;;;2EAIuE;IACvE,KAAK,CAAC,EAAE,2BAA2B,GAAG,IAAI,CAAC;CAC5C;AAoDD;;;;;;;;GAQG;AACH,eAAO,MAAM,uBAAuB,GAClC,KAAK,YAAY,EACjB,UAAU,8BAA8B,KACvC,OAAO,CAAC,qBAAqB,CAmC/B,CAAC;AAEF,kFAAkF;AAClF,mFAAmF;AACnF,eAAO,MAAM,qBAAqB,GAChC,KAAK,YAAY,EACjB,QAAQ,qBAAqB,KAC5B,eAA2F,CAAC;AAI/F,mBAAmB,yBAAyB,CAAC;AAG7C,OAAO,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AAE/D;;;;;2EAK2E;AAC3E,mFAAmF;AACnF,eAAO,MAAM,uBAAuB,GAClC,KAAK,YAAY,EACjB,QAAQ,yBAAyB,KAChC,mBAA0F,CAAC;AAE9F,YAAY,EAAE,mBAAmB,IAAI,gBAAgB,EAAE,yBAAyB,IAAI,sBAAsB,EAAE,CAAC"}
|
package/dist/index.js
CHANGED
|
@@ -30,10 +30,57 @@ export { probeWalletAvailability, PciWalletTopUpElement, openWalletTopUpPopup, }
|
|
|
30
30
|
* the app config), so it does not partition the cache. Failed probes are not
|
|
31
31
|
* cached. */
|
|
32
32
|
const availabilityCache = new Map();
|
|
33
|
+
const AVAILABILITY_CACHE_PREFIX = 'wx.card-sdk.wallet-availability.v1:';
|
|
34
|
+
/** Storage access itself can throw (privacy modes, disabled cookies) —
|
|
35
|
+
* degrade to "no persistence", never to a broken probe. */
|
|
36
|
+
const defaultAvailabilityCache = () => {
|
|
37
|
+
try {
|
|
38
|
+
return typeof window === 'undefined' ? null : window.localStorage;
|
|
39
|
+
}
|
|
40
|
+
catch {
|
|
41
|
+
return null;
|
|
42
|
+
}
|
|
43
|
+
};
|
|
44
|
+
const availabilityCacheKey = (frameUrl) => {
|
|
45
|
+
try {
|
|
46
|
+
// Keyed by frame ORIGIN: different environments answer differently.
|
|
47
|
+
return AVAILABILITY_CACHE_PREFIX + new URL(frameUrl, window.location.href).origin;
|
|
48
|
+
}
|
|
49
|
+
catch {
|
|
50
|
+
return AVAILABILITY_CACHE_PREFIX + frameUrl;
|
|
51
|
+
}
|
|
52
|
+
};
|
|
53
|
+
const readPersistedAvailability = (cache, key) => {
|
|
54
|
+
try {
|
|
55
|
+
const raw = cache.getItem(key);
|
|
56
|
+
if (!raw)
|
|
57
|
+
return null;
|
|
58
|
+
const parsed = JSON.parse(raw);
|
|
59
|
+
if (typeof parsed.applePay === 'boolean' && typeof parsed.googlePay === 'boolean') {
|
|
60
|
+
return { applePay: parsed.applePay, googlePay: parsed.googlePay };
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
catch {
|
|
64
|
+
/* corrupted entry — behave as uncached; the fresh probe rewrites it */
|
|
65
|
+
}
|
|
66
|
+
return null;
|
|
67
|
+
};
|
|
68
|
+
const writePersistedAvailability = (cache, key, value) => {
|
|
69
|
+
try {
|
|
70
|
+
cache.setItem(key, JSON.stringify(value));
|
|
71
|
+
}
|
|
72
|
+
catch {
|
|
73
|
+
/* quota/privacy errors — persistence is an optimization only */
|
|
74
|
+
}
|
|
75
|
+
};
|
|
33
76
|
/**
|
|
34
77
|
* Phase-A availability check. Run it before showing the wallet row at all —
|
|
35
78
|
* `false` means hide the row (`googlePay: false` on desktop/non-Chrome is
|
|
36
79
|
* expected: the cryptogram-only policy has no eligible cards there).
|
|
80
|
+
*
|
|
81
|
+
* Resolution order: in-memory (per page session) → the persistent cache
|
|
82
|
+
* (instant answer + background revalidation) → the live probe. `force: true`
|
|
83
|
+
* skips both caches and awaits a fresh probe.
|
|
37
84
|
*/
|
|
38
85
|
export const checkWalletAvailability = (sdk, options) => {
|
|
39
86
|
const frameUrl = buildFrameUrl(sdk, 'wallet-probe');
|
|
@@ -42,10 +89,31 @@ export const checkWalletAvailability = (sdk, options) => {
|
|
|
42
89
|
if (cached)
|
|
43
90
|
return cached;
|
|
44
91
|
}
|
|
45
|
-
const
|
|
92
|
+
const cache = options?.cache === undefined ? defaultAvailabilityCache() : options.cache;
|
|
93
|
+
const cacheKey = availabilityCacheKey(frameUrl);
|
|
94
|
+
const probe = probeWalletAvailability(frameUrl, options?.config)
|
|
95
|
+
.then(fresh => {
|
|
96
|
+
if (cache)
|
|
97
|
+
writePersistedAvailability(cache, cacheKey, fresh);
|
|
98
|
+
// Later callers this session get the FRESH answer, not the stale one.
|
|
99
|
+
availabilityCache.set(frameUrl, Promise.resolve(fresh));
|
|
100
|
+
return fresh;
|
|
101
|
+
})
|
|
102
|
+
.catch((error) => {
|
|
46
103
|
availabilityCache.delete(frameUrl);
|
|
47
104
|
throw error;
|
|
48
105
|
});
|
|
106
|
+
const persisted = !options?.force && cache ? readPersistedAvailability(cache, cacheKey) : null;
|
|
107
|
+
if (persisted) {
|
|
108
|
+
// Stale-while-revalidate: resolve instantly from the last real answer;
|
|
109
|
+
// the live probe above keeps running and refreshes both caches. Its
|
|
110
|
+
// failure is already handled (cache eviction) — never an unhandled
|
|
111
|
+
// rejection here.
|
|
112
|
+
probe.catch(() => undefined);
|
|
113
|
+
const instant = Promise.resolve(persisted);
|
|
114
|
+
availabilityCache.set(frameUrl, instant);
|
|
115
|
+
return instant;
|
|
116
|
+
}
|
|
49
117
|
availabilityCache.set(frameUrl, probe);
|
|
50
118
|
return probe;
|
|
51
119
|
};
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;GAiBG;AACH,OAAO,EACL,aAAa,GAId,MAAM,yBAAyB,CAAC;AACjC,OAAO,EACL,uBAAuB,EACvB,qBAAqB,GAEtB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EACL,oBAAoB,GAGrB,MAAM,eAAe,CAAC;AAEvB,6EAA6E;AAC7E,0EAA0E;AAC1E,4EAA4E;AAC5E,0CAA0C;AAC1C,OAAO,EACL,uBAAuB,EACvB,qBAAqB,EACrB,oBAAoB,GACrB,CAAC;AAYF;;;;cAIc;AACd,MAAM,iBAAiB,GAAG,IAAI,GAAG,EAA0C,CAAC;
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletPopup.d.ts","sourceRoot":"","sources":["../src/walletPopup.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;
|
|
1
|
+
{"version":3,"file":"walletPopup.d.ts","sourceRoot":"","sources":["../src/walletPopup.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,2BAA2B,EAAE,MAAM,iBAAiB,CAAC;AA0BnE,MAAM,WAAW,yBAA0B,SAAQ,IAAI,CAAC,2BAA2B,EAAE,OAAO,GAAG,cAAc,CAAC;IAC5G;;;oEAGgE;IAChE,KAAK,CAAC,EAAE,2BAA2B,CAAC,OAAO,CAAC,CAAC;IAC7C,YAAY,CAAC,EAAE,2BAA2B,CAAC,cAAc,CAAC,CAAC;IAC3D;6EACyE;IACzE,OAAO,CAAC,EAAE,MAAM,IAAI,CAAC;IACrB;2DACuD;IACvD,YAAY,CAAC,EAAE,CAAC,KAAK,EAAE,KAAK,KAAK,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IAClC;;oEAEgE;IAChE,GAAG,CAAC,KAAK,EAAE,2BAA2B,CAAC,OAAO,CAAC,EAAE,YAAY,EAAE,2BAA2B,CAAC,cAAc,CAAC,GAAG,IAAI,CAAC;IAClH;uCACmC;IACnC,MAAM,CAAC,KAAK,EAAE,2BAA2B,CAAC,OAAO,CAAC,EAAE,YAAY,CAAC,EAAE,2BAA2B,CAAC,cAAc,CAAC,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/H,qEAAqE;IACrE,KAAK,IAAI,IAAI,CAAC;CACf;AAED;;;GAGG;AACH,eAAO,MAAM,oBAAoB,GAC/B,UAAU,MAAM,EAChB,QAAQ,yBAAyB,KAChC,mBAqLF,CAAC"}
|
package/dist/walletPopup.js
CHANGED
|
@@ -20,7 +20,16 @@ const READY_TIMEOUT_MS = 15000;
|
|
|
20
20
|
const REQUEST_TIMEOUT_MS = 30000;
|
|
21
21
|
const CLOSE_POLL_MS = 400;
|
|
22
22
|
/** ~mobile-sheet proportions, centered by the browser. */
|
|
23
|
-
const
|
|
23
|
+
const POPUP_WIDTH = 430;
|
|
24
|
+
const POPUP_HEIGHT = 780;
|
|
25
|
+
/** Centered over the CURRENT browser window (screenX/outerWidth include the
|
|
26
|
+
* monitor offset, so multi-display setups center correctly; the browser
|
|
27
|
+
* clamps out-of-screen coordinates itself). */
|
|
28
|
+
const popupFeatures = () => {
|
|
29
|
+
const left = Math.max(0, Math.round((window.screenX ?? 0) + ((window.outerWidth || POPUP_WIDTH) - POPUP_WIDTH) / 2));
|
|
30
|
+
const top = Math.max(0, Math.round((window.screenY ?? 0) + ((window.outerHeight || POPUP_HEIGHT) - POPUP_HEIGHT) / 2));
|
|
31
|
+
return `popup=yes,width=${POPUP_WIDTH},height=${POPUP_HEIGHT},left=${left},top=${top},resizable=yes,scrollbars=yes`;
|
|
32
|
+
};
|
|
24
33
|
/** The checkout renders on a transparent surface for iframes; a top-level
|
|
25
34
|
* popup needs an opaque ground. Overridable via appearance.surfaceColor. */
|
|
26
35
|
const POPUP_DEFAULT_SURFACE = '#141414';
|
|
@@ -34,8 +43,14 @@ const randomId = () => typeof crypto !== 'undefined' && 'randomUUID' in crypto
|
|
|
34
43
|
export const openWalletTopUpPopup = (frameUrl, config) => {
|
|
35
44
|
const frameOrigin = new URL(frameUrl, window.location.href).origin;
|
|
36
45
|
const channelId = randomId();
|
|
37
|
-
|
|
38
|
-
|
|
46
|
+
// Appearance rides the FRAGMENT so the popup's loading skeleton renders
|
|
47
|
+
// themed before the first `arm()` — the frame validates it against the
|
|
48
|
+
// same allowlist as init, and fragments never reach the server.
|
|
49
|
+
const appearanceFragment = config.appearance
|
|
50
|
+
? `&appearance=${encodeURIComponent(JSON.stringify(config.appearance))}`
|
|
51
|
+
: '';
|
|
52
|
+
const url = `${frameUrl}#channel=${channelId}&parent=${encodeURIComponent(window.location.origin)}${appearanceFragment}`;
|
|
53
|
+
const popup = window.open(url, '_blank', popupFeatures());
|
|
39
54
|
const pending = new Map();
|
|
40
55
|
let settled = false; // a token was handed off
|
|
41
56
|
let closed = false;
|
package/dist/walletPopup.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"walletPopup.js","sourceRoot":"","sources":["../src/walletPopup.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;GAgBG;AACH,OAAO,EAAE,oBAAoB,EAA0D,MAAM,yBAAyB,CAAC;AAGvH,MAAM,gBAAgB,GAAG,KAAM,CAAC;AAChC,MAAM,kBAAkB,GAAG,KAAM,CAAC;AAClC,MAAM,aAAa,GAAG,GAAG,CAAC;AAC1B,0DAA0D;AAC1D,MAAM,
|
|
1
|
+
{"version":3,"file":"walletPopup.js","sourceRoot":"","sources":["../src/walletPopup.ts"],"names":[],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@wirexapp/card-wallet-topup-web",
|
|
3
|
-
"version": "1.1.0-beta.
|
|
3
|
+
"version": "1.1.0-beta.2",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"description": "Top up via Apple Pay / Google Pay inside a Wirex-served checkout iframe — review screen + wallet buttons under Wirex's merchant identity; the payment sheet's encrypted token is returned to the host, which executes the top-up. No wallet onboarding on the partner side.",
|
|
6
6
|
"license": "UNLICENSED",
|
|
@@ -37,6 +37,6 @@
|
|
|
37
37
|
"prepublishOnly": "yarn clean && yarn build"
|
|
38
38
|
},
|
|
39
39
|
"dependencies": {
|
|
40
|
-
"@wirexapp/card-sdk-core": "1.1.0-beta.
|
|
40
|
+
"@wirexapp/card-sdk-core": "1.1.0-beta.2"
|
|
41
41
|
}
|
|
42
42
|
}
|