@notabene/javascript-sdk 2.7.0 → 2.8.0-next.1
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/dist/notabene.cjs +1 -1
- package/dist/notabene.d.ts +13 -2
- package/dist/notabene.js +3 -3
- package/package.json +1 -1
- package/src/__tests__/EmbeddedComponent.test.ts +222 -0
- package/src/types.ts +19 -2
package/dist/notabene.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";var L=Object.defineProperty;var A=(e,t,r)=>t in e?L(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var o=(e,t,r)=>A(e,typeof t!="symbol"?t+"":t,r);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var c=(e=>(e.PRIVATE="WALLET",e.VASP="VASP",e))(c||{}),m=(e=>(e.NATURAL="natural",e.LEGAL="legal",e.SELF="self",e))(m||{}),u=(e=>(e.EMPTY="empty",e.VERIFY="verify",e.PENDING="pending",e.VERIFIED="verified",e.BANNED="banned",e))(u||{}),E=(e=>(e.ALLOWED="allowed",e.PENDING="pending",e))(E||{}),p=(e=>(e.ASSET="asset",e.DESTINATION="destination",e.COUNTERPARTY="counterparty",e.AGENT="agent",e))(p||{}),a=(e=>(e.COMPLETE="complete",e.RESIZE="resize",e.RESULT="result",e.READY="ready",e.INVALID="invalid",e.ERROR="error",e.CANCEL="cancel",e))(a||{}),f=(e=>(e.SERVICE_UNAVAILABLE="SERVICE_UNAVAILABLE",e.WALLET_CONNECTION_FAILED="WALLET_CONNECTION_FAILED",e.WALLET_NOT_SUPPORTED="WALLET_NOT_SUPPORTED",e.TOKEN_INVALID="TOKEN_INVALID",e))(f||{}),d=(e=>(e.UPDATE="update",e.REQUEST_RESPONSE="requestResponse",e))(d||{}),v=(e=>(e.PENDING="pending",e.FAILED="rejected",e.FLAGGED="flagged",e.VERIFIED="verified",e))(v||{}),I=(e=>(e.SelfDeclaration="self-declaration",e.SIWE="siwe",e.SIWX="siwx",e.EIP191="eip-191",e.EIP712="eip-712",e.EIP1271="eip-1271",e.BIP137="bip-137",e.BIP322="bip-322",e.BIP137_XPUB="xpub",e.TIP191="tip-191",e.ED25519="ed25519",e.CIP8="cip-8",e.MicroTransfer="microtransfer",e.Screenshot="screenshot",e.Connect="connect",e))(I||{});class N{constructor(){o(this,"listeners",new Map);o(this,"port");this.handleMessage=this.handleMessage.bind(this)}setPort(t){this.port=t,this.port.onmessage=this.handleMessage,this.port.start()}on(t,r){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(r),()=>this.off(t,r)}off(t,r){const
|
|
1
|
+
"use strict";var L=Object.defineProperty;var A=(e,t,r)=>t in e?L(e,t,{enumerable:!0,configurable:!0,writable:!0,value:r}):e[t]=r;var o=(e,t,r)=>A(e,typeof t!="symbol"?t+"":t,r);Object.defineProperties(exports,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}});var c=(e=>(e.PRIVATE="WALLET",e.VASP="VASP",e))(c||{}),m=(e=>(e.NATURAL="natural",e.LEGAL="legal",e.SELF="self",e))(m||{}),u=(e=>(e.EMPTY="empty",e.VERIFY="verify",e.PENDING="pending",e.VERIFIED="verified",e.BANNED="banned",e))(u||{}),E=(e=>(e.ALLOWED="allowed",e.PENDING="pending",e))(E||{}),p=(e=>(e.ASSET="asset",e.DESTINATION="destination",e.COUNTERPARTY="counterparty",e.AGENT="agent",e))(p||{}),a=(e=>(e.COMPLETE="complete",e.RESIZE="resize",e.RESULT="result",e.READY="ready",e.INVALID="invalid",e.ERROR="error",e.CANCEL="cancel",e))(a||{}),f=(e=>(e.SERVICE_UNAVAILABLE="SERVICE_UNAVAILABLE",e.WALLET_CONNECTION_FAILED="WALLET_CONNECTION_FAILED",e.WALLET_NOT_SUPPORTED="WALLET_NOT_SUPPORTED",e.TOKEN_INVALID="TOKEN_INVALID",e))(f||{}),d=(e=>(e.UPDATE="update",e.REQUEST_RESPONSE="requestResponse",e))(d||{}),v=(e=>(e.PENDING="pending",e.FAILED="rejected",e.FLAGGED="flagged",e.VERIFIED="verified",e))(v||{}),I=(e=>(e.SelfDeclaration="self-declaration",e.SIWE="siwe",e.SIWX="siwx",e.EIP191="eip-191",e.EIP712="eip-712",e.EIP1271="eip-1271",e.BIP137="bip-137",e.BIP322="bip-322",e.BIP137_XPUB="xpub",e.TIP191="tip-191",e.ED25519="ed25519",e.XRP_ED25519="xrp-ed25519",e.CIP8="cip-8",e.MicroTransfer="microtransfer",e.Screenshot="screenshot",e.Connect="connect",e))(I||{});class N{constructor(){o(this,"listeners",new Map);o(this,"port");this.handleMessage=this.handleMessage.bind(this)}setPort(t){this.port=t,this.port.onmessage=this.handleMessage,this.port.start()}on(t,r){return this.listeners.has(t)||this.listeners.set(t,new Set),this.listeners.get(t).add(r),()=>this.off(t,r)}off(t,r){const i=this.listeners.get(t);i&&(i.delete(r),i.size===0&&this.listeners.delete(t))}handleMessage(t){const r=t.data;if(typeof r=="object"&&r!==null&&"type"in r){const i=r.type,s=this.listeners.get(i);s&&s.forEach(n=>n(r))}}send(t){this.port&&this.port.postMessage(t)}}class g{constructor(t,r,i){o(this,"_url");o(this,"_value");o(this,"_options");o(this,"_errors",[]);o(this,"iframe");o(this,"eventManager");o(this,"modal");this._url=t,this._value=r,this._options=i,this.eventManager=new N,this.on(a.INVALID,s=>{s.type===a.INVALID&&(this._errors=s.errors,this._value=s.value)}),this.on(a.RESIZE,s=>{s.type===a.RESIZE&&this.iframe&&(this.iframe.style.height=`${s.height}px`)})}get url(){return this._url}get value(){return this._value}get options(){return this._options}get errors(){return this._errors}open(){document.location.href=this.url}mount(t){const r=document.querySelector(t);if(!r)throw new Error(`parentID ${t} not found`);this.embed(r)}embed(t,r=!1){var i,s;this.removeEmbed(),this.iframe=document.createElement("iframe"),this.iframe.src=this.url+(r?"":"&embedded=true"),this.iframe.allow="web-share; clipboard-write; hid; bluetooth;",this.iframe.style.width="100%",this.iframe.style.height="0px",this.iframe.style.border="none",this.iframe.style.overflow="hidden",this.iframe.scrolling="no",t.appendChild(this.iframe),window.addEventListener("message",n=>{var l,h;n.source===((l=this.iframe)==null?void 0:l.contentWindow)&&((h=this.eventManager)==null||h.setPort(n.ports[0]))}),(s=(i=this.iframe)==null?void 0:i.contentWindow)==null||s.focus()}removeEmbed(){this.iframe&&this.iframe.remove()}send(t){this.eventManager.send(t)}on(t,r){return this.eventManager.on(t,r)}off(t,r){this.eventManager.off(t,r)}update(t,r){this._value=t,r&&(this._options=r),this.send({type:d.UPDATE,value:t,options:this._options})}completion(){return new Promise((t,r)=>{let i,s,n;function l(){i&&i(),s&&s(),n&&n()}i=this.on(a.COMPLETE,h=>{t(h.response),l()}),s=this.on(a.CANCEL,()=>{r(new Error("User cancelled")),l()}),n=this.on("error",h=>{r(new Error(h.message)),l()})})}async openModal(){this.modal&&this.closeModal(),this.modal=document.createElement("dialog"),this.modal.style.border="none",this.modal.style.backgroundColor="white",this.modal.style.maxWidth="100vw",this.modal.style.maxHeight="100vh",this.modal.style.width="600px",this.modal.style.height="600px",document.body.appendChild(this.modal),this.embed(this.modal,!0);const t=this.on(a.CANCEL,()=>{this.closeModal()}),r=this.on(a.COMPLETE,()=>{this.closeModal()});return this.modal.showModal(),this.modal.addEventListener("click",()=>{this.closeModal()}),this.completion().finally(()=>{t(),r()})}closeModal(){var t;this.modal&&((t=this.modal)==null||t.close(),this.modal.remove(),this.modal=void 0)}async popup(){const t=window.open(this.url,"_blank","popup=true,width=600,height=600");window.addEventListener("message",s=>{var n;s.source===t&&(console.log("received message from popup",s.data),(n=this.eventManager)==null||n.setPort(s.ports[0]))});const r=this.on(a.CANCEL,()=>{t==null||t.close()}),i=this.on(a.COMPLETE,()=>{t==null||t.close()});return this.completion().finally(()=>{r(),i()})}}function _(e){return Object.entries(e).map(([t,r])=>{if(r==null)return;const i=encodeURIComponent(t),s=encodeURIComponent(typeof r=="object"?JSON.stringify(r):String(r));return`${i}=${s}`}).filter(t=>t!==void 0).join("&")}function w(e){const t=e.slice(1);return t?t.split("&").filter(Boolean).reduce((i,s)=>{const[n,l]=s.split("=");return n&&(i[decodeURIComponent(n)]=l?decodeURIComponent(l):""),i},{}):{}}class C{constructor(t){o(this,"nodeUrl");o(this,"authToken");o(this,"uxUrl");o(this,"theme");o(this,"locale");this.uxUrl=t.uxUrl||"https://connect.notabene.id",this.nodeUrl=t.nodeUrl,this.authToken=t.authToken,this.theme=t.theme,this.locale=t.locale}componentUrl(t,r,i,s){const n=new URL(this.uxUrl);n.pathname=t;const l=_({authToken:this.authToken,value:r,configuration:i});return n.hash=l,this.nodeUrl&&n.searchParams.set("nodeUrl",this.nodeUrl),this.theme&&n.searchParams.set("theme",JSON.stringify(this.theme)),this.locale&&n.searchParams.set("locale",this.locale),s&&(s.callback&&n.searchParams.set("callback_url",s.callback),s.redirectUri&&n.searchParams.set("redirect_uri",s.redirectUri)),n.toString()}createComponent(t,r,i,s){return new g(this.componentUrl(t,r,i,s),r,i)}createWithdrawalAssist(t,r,i){return this.createComponent("withdrawal-assist",t,r,i)}createConnectWallet(t,r,i){return this.createComponent("connect",t,r,i)}createDepositRequest(t,r,i){return this.createComponent("deposit-request",t,r,i)}createDepositAssist(t,r,i){return this.createComponent("deposit-assist",t,r,i)}}exports.AgentType=c;exports.CMType=a;exports.EmbeddedComponent=g;exports.ErrorIdentifierCode=f;exports.HMType=d;exports.PersonType=m;exports.ProofStatus=v;exports.ProofTypes=I;exports.Status=u;exports.VASPSearchControl=E;exports.ValidationSections=p;exports.decodeFragmentToObject=w;exports.default=C;
|
package/dist/notabene.d.ts
CHANGED
|
@@ -383,7 +383,7 @@ export declare function decodeFragmentToObject(fragment: string): Record<string,
|
|
|
383
383
|
* An object representing a deposit transaction
|
|
384
384
|
* @public
|
|
385
385
|
*/
|
|
386
|
-
export declare interface Deposit extends OriginatorFields, DepositTransaction {
|
|
386
|
+
export declare interface Deposit extends OriginatorFields, DepositTransaction, Refreshable {
|
|
387
387
|
}
|
|
388
388
|
|
|
389
389
|
/**
|
|
@@ -1225,6 +1225,7 @@ export declare enum ProofStatus {
|
|
|
1225
1225
|
* - BIP322: Bitcoin message signature following BIP-322
|
|
1226
1226
|
* - TIP191: Tron message signing
|
|
1227
1227
|
* - ED25519: Ed25519 signature (used in Solana)
|
|
1228
|
+
* - XRP_ED25519: Ed25519 signature (used in XRP)
|
|
1228
1229
|
* - XPUB: Extended public key signature for HD wallets
|
|
1229
1230
|
* - MicroTransfer: Proof via small blockchain transaction
|
|
1230
1231
|
* - Screenshot: Image proof of ownership/access
|
|
@@ -1248,6 +1249,7 @@ export declare enum ProofTypes {
|
|
|
1248
1249
|
BIP137_XPUB = "xpub",
|
|
1249
1250
|
TIP191 = "tip-191",
|
|
1250
1251
|
ED25519 = "ed25519",
|
|
1252
|
+
XRP_ED25519 = "xrp-ed25519",
|
|
1251
1253
|
CIP8 = "cip-8",
|
|
1252
1254
|
MicroTransfer = "microtransfer",
|
|
1253
1255
|
Screenshot = "screenshot",
|
|
@@ -1262,6 +1264,15 @@ export declare type Ready = {
|
|
|
1262
1264
|
type: CMType.READY;
|
|
1263
1265
|
};
|
|
1264
1266
|
|
|
1267
|
+
declare interface Refreshable {
|
|
1268
|
+
refreshSource?: RefreshSource;
|
|
1269
|
+
}
|
|
1270
|
+
|
|
1271
|
+
declare interface RefreshSource {
|
|
1272
|
+
url: URI;
|
|
1273
|
+
key: string;
|
|
1274
|
+
}
|
|
1275
|
+
|
|
1265
1276
|
declare type RequestID = UUID;
|
|
1266
1277
|
|
|
1267
1278
|
/**
|
|
@@ -1628,7 +1639,7 @@ export declare interface Wallet extends Agent {
|
|
|
1628
1639
|
* An object representing a withdrawal transaction
|
|
1629
1640
|
* @public
|
|
1630
1641
|
*/
|
|
1631
|
-
export declare interface Withdrawal extends BeneficiaryFields, Transaction {
|
|
1642
|
+
export declare interface Withdrawal extends BeneficiaryFields, Transaction, Refreshable {
|
|
1632
1643
|
}
|
|
1633
1644
|
|
|
1634
1645
|
export { }
|
package/dist/notabene.js
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
var c = Object.defineProperty;
|
|
2
2
|
var m = (e, t, r) => t in e ? c(e, t, { enumerable: !0, configurable: !0, writable: !0, value: r }) : e[t] = r;
|
|
3
3
|
var o = (e, t, r) => m(e, typeof t != "symbol" ? t + "" : t, r);
|
|
4
|
-
var u = /* @__PURE__ */ ((e) => (e.PRIVATE = "WALLET", e.VASP = "VASP", e))(u || {}), E = /* @__PURE__ */ ((e) => (e.NATURAL = "natural", e.LEGAL = "legal", e.SELF = "self", e))(E || {}),
|
|
4
|
+
var u = /* @__PURE__ */ ((e) => (e.PRIVATE = "WALLET", e.VASP = "VASP", e))(u || {}), E = /* @__PURE__ */ ((e) => (e.NATURAL = "natural", e.LEGAL = "legal", e.SELF = "self", e))(E || {}), p = /* @__PURE__ */ ((e) => (e.EMPTY = "empty", e.VERIFY = "verify", e.PENDING = "pending", e.VERIFIED = "verified", e.BANNED = "banned", e))(p || {}), f = /* @__PURE__ */ ((e) => (e.ALLOWED = "allowed", e.PENDING = "pending", e))(f || {}), v = /* @__PURE__ */ ((e) => (e.ASSET = "asset", e.DESTINATION = "destination", e.COUNTERPARTY = "counterparty", e.AGENT = "agent", e))(v || {}), h = /* @__PURE__ */ ((e) => (e.COMPLETE = "complete", e.RESIZE = "resize", e.RESULT = "result", e.READY = "ready", e.INVALID = "invalid", e.ERROR = "error", e.CANCEL = "cancel", e))(h || {}), I = /* @__PURE__ */ ((e) => (e.SERVICE_UNAVAILABLE = "SERVICE_UNAVAILABLE", e.WALLET_CONNECTION_FAILED = "WALLET_CONNECTION_FAILED", e.WALLET_NOT_SUPPORTED = "WALLET_NOT_SUPPORTED", e.TOKEN_INVALID = "TOKEN_INVALID", e))(I || {}), d = /* @__PURE__ */ ((e) => (e.UPDATE = "update", e.REQUEST_RESPONSE = "requestResponse", e))(d || {}), L = /* @__PURE__ */ ((e) => (e.PENDING = "pending", e.FAILED = "rejected", e.FLAGGED = "flagged", e.VERIFIED = "verified", e))(L || {}), g = /* @__PURE__ */ ((e) => (e.SelfDeclaration = "self-declaration", e.SIWE = "siwe", e.SIWX = "siwx", e.EIP191 = "eip-191", e.EIP712 = "eip-712", e.EIP1271 = "eip-1271", e.BIP137 = "bip-137", e.BIP322 = "bip-322", e.BIP137_XPUB = "xpub", e.TIP191 = "tip-191", e.ED25519 = "ed25519", e.XRP_ED25519 = "xrp-ed25519", e.CIP8 = "cip-8", e.MicroTransfer = "microtransfer", e.Screenshot = "screenshot", e.Connect = "connect", e))(g || {});
|
|
5
5
|
class A {
|
|
6
6
|
constructor() {
|
|
7
7
|
o(this, "listeners", /* @__PURE__ */ new Map());
|
|
@@ -385,8 +385,8 @@ export {
|
|
|
385
385
|
E as PersonType,
|
|
386
386
|
L as ProofStatus,
|
|
387
387
|
g as ProofTypes,
|
|
388
|
-
|
|
389
|
-
|
|
388
|
+
p as Status,
|
|
389
|
+
f as VASPSearchControl,
|
|
390
390
|
v as ValidationSections,
|
|
391
391
|
C as decodeFragmentToObject,
|
|
392
392
|
U as default
|
package/package.json
CHANGED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
import { beforeEach, describe, expect, test, vi } from 'vitest';
|
|
2
|
+
import EmbeddedComponent from '../components/EmbeddedComponent';
|
|
3
|
+
import { CMType, HMType } from '../types';
|
|
4
|
+
|
|
5
|
+
// Simple test interfaces
|
|
6
|
+
interface TestValue {
|
|
7
|
+
name?: string;
|
|
8
|
+
amount?: number;
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
interface TestOptions {
|
|
12
|
+
currency?: string;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
// Mock MessageEventManager
|
|
16
|
+
vi.mock('../utils/MessageEventManager', () => {
|
|
17
|
+
return {
|
|
18
|
+
MessageEventManager: vi.fn().mockImplementation(() => ({
|
|
19
|
+
on: vi.fn((type, callback) => {
|
|
20
|
+
callbacks.set(type, callback);
|
|
21
|
+
return () => callbacks.delete(type);
|
|
22
|
+
}),
|
|
23
|
+
send: vi.fn((message) => {
|
|
24
|
+
const callback = callbacks.get(message.type);
|
|
25
|
+
if (callback) callback(message);
|
|
26
|
+
}),
|
|
27
|
+
off: vi.fn(),
|
|
28
|
+
setPort: vi.fn(),
|
|
29
|
+
})),
|
|
30
|
+
};
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
// Store callbacks for testing
|
|
34
|
+
const callbacks = new Map();
|
|
35
|
+
|
|
36
|
+
describe('EmbeddedComponent', () => {
|
|
37
|
+
let mockParent: HTMLElement;
|
|
38
|
+
let mockAppendChild: ReturnType<typeof vi.fn>;
|
|
39
|
+
|
|
40
|
+
beforeEach(() => {
|
|
41
|
+
// Clear callbacks before each test
|
|
42
|
+
callbacks.clear();
|
|
43
|
+
|
|
44
|
+
mockParent = document.createElement('div');
|
|
45
|
+
vi.spyOn(document, 'querySelector').mockReturnValue(mockParent);
|
|
46
|
+
mockAppendChild = vi.fn().mockImplementation((node: Node) => node);
|
|
47
|
+
vi.spyOn(mockParent, 'appendChild').mockImplementation(mockAppendChild);
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
describe('initialization', () => {
|
|
51
|
+
test('should initialize with basic values', () => {
|
|
52
|
+
const url = 'https://example.com';
|
|
53
|
+
const value = { name: 'Test' };
|
|
54
|
+
const options = { currency: 'USD' };
|
|
55
|
+
|
|
56
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
57
|
+
url,
|
|
58
|
+
value,
|
|
59
|
+
options,
|
|
60
|
+
);
|
|
61
|
+
|
|
62
|
+
expect(component.url).toBe(url);
|
|
63
|
+
expect(component.value).toEqual(value);
|
|
64
|
+
expect(component.options).toEqual(options);
|
|
65
|
+
expect(component.errors).toEqual([]);
|
|
66
|
+
});
|
|
67
|
+
|
|
68
|
+
test('should initialize without options', () => {
|
|
69
|
+
const url = 'https://example.com';
|
|
70
|
+
const value = { name: 'Test' };
|
|
71
|
+
|
|
72
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
73
|
+
url,
|
|
74
|
+
value,
|
|
75
|
+
);
|
|
76
|
+
|
|
77
|
+
expect(component.url).toBe(url);
|
|
78
|
+
expect(component.value).toEqual(value);
|
|
79
|
+
expect(component.options).toBeUndefined();
|
|
80
|
+
expect(component.errors).toEqual([]);
|
|
81
|
+
});
|
|
82
|
+
});
|
|
83
|
+
|
|
84
|
+
describe('value updates', () => {
|
|
85
|
+
test('should update value', () => {
|
|
86
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
87
|
+
'https://example.com',
|
|
88
|
+
{},
|
|
89
|
+
);
|
|
90
|
+
const newValue = { name: 'Updated', amount: 100 };
|
|
91
|
+
|
|
92
|
+
component.update(newValue);
|
|
93
|
+
|
|
94
|
+
expect(component.value).toEqual(newValue);
|
|
95
|
+
});
|
|
96
|
+
|
|
97
|
+
test('should update value and options', () => {
|
|
98
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
99
|
+
'https://example.com',
|
|
100
|
+
{},
|
|
101
|
+
);
|
|
102
|
+
const newValue = { name: 'Updated', amount: 100 };
|
|
103
|
+
const newOptions = { currency: 'EUR' };
|
|
104
|
+
|
|
105
|
+
component.update(newValue, newOptions);
|
|
106
|
+
|
|
107
|
+
expect(component.value).toEqual(newValue);
|
|
108
|
+
expect(component.options).toEqual(newOptions);
|
|
109
|
+
});
|
|
110
|
+
});
|
|
111
|
+
|
|
112
|
+
describe('mounting', () => {
|
|
113
|
+
test('should mount component to parent element', () => {
|
|
114
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
115
|
+
'https://example.com',
|
|
116
|
+
{},
|
|
117
|
+
);
|
|
118
|
+
|
|
119
|
+
component.mount('#parent');
|
|
120
|
+
|
|
121
|
+
expect(document.querySelector).toHaveBeenCalledWith('#parent');
|
|
122
|
+
const iframe = mockAppendChild.mock.calls[0][0] as HTMLIFrameElement;
|
|
123
|
+
expect(iframe).toBeTruthy();
|
|
124
|
+
expect(iframe.src).toBe('https://example.com&embedded=true/');
|
|
125
|
+
expect(iframe.style.width).toBe('100%');
|
|
126
|
+
expect(iframe.style.height).toBe('0px');
|
|
127
|
+
expect(iframe.style.border).toBe('');
|
|
128
|
+
});
|
|
129
|
+
|
|
130
|
+
test('should throw error if parent element not found', () => {
|
|
131
|
+
vi.spyOn(document, 'querySelector').mockReturnValue(null);
|
|
132
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
133
|
+
'https://example.com',
|
|
134
|
+
{},
|
|
135
|
+
);
|
|
136
|
+
|
|
137
|
+
expect(() => component.mount('#nonexistent')).toThrow(
|
|
138
|
+
'parentID #nonexistent not found',
|
|
139
|
+
);
|
|
140
|
+
});
|
|
141
|
+
|
|
142
|
+
test('should remove existing iframe when mounting again', () => {
|
|
143
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
144
|
+
'https://example.com',
|
|
145
|
+
{},
|
|
146
|
+
);
|
|
147
|
+
|
|
148
|
+
// First mount
|
|
149
|
+
component.mount('#parent');
|
|
150
|
+
const firstIframe = mockAppendChild.mock.calls[0][0] as HTMLIFrameElement;
|
|
151
|
+
const removeSpy = vi.spyOn(firstIframe, 'remove');
|
|
152
|
+
|
|
153
|
+
// Second mount
|
|
154
|
+
component.mount('#parent');
|
|
155
|
+
|
|
156
|
+
expect(removeSpy).toHaveBeenCalled();
|
|
157
|
+
expect(mockAppendChild).toHaveBeenCalledTimes(2);
|
|
158
|
+
});
|
|
159
|
+
});
|
|
160
|
+
|
|
161
|
+
describe('event handling', () => {
|
|
162
|
+
test('should register and unregister event listeners', () => {
|
|
163
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
164
|
+
'https://example.com',
|
|
165
|
+
{},
|
|
166
|
+
);
|
|
167
|
+
const mockCallback = vi.fn();
|
|
168
|
+
|
|
169
|
+
// Register event listener
|
|
170
|
+
const unsubscribe = component.on(HMType.UPDATE, mockCallback);
|
|
171
|
+
|
|
172
|
+
// Send a message
|
|
173
|
+
component.send({ type: HMType.UPDATE, value: { name: 'test' } });
|
|
174
|
+
expect(mockCallback).toHaveBeenCalledTimes(1);
|
|
175
|
+
expect(mockCallback).toHaveBeenCalledWith({
|
|
176
|
+
type: HMType.UPDATE,
|
|
177
|
+
value: { name: 'test' },
|
|
178
|
+
});
|
|
179
|
+
|
|
180
|
+
// Unsubscribe and send again
|
|
181
|
+
unsubscribe();
|
|
182
|
+
component.send({ type: HMType.UPDATE, value: { name: 'test2' } });
|
|
183
|
+
expect(mockCallback).toHaveBeenCalledTimes(1); // Still 1, not called again
|
|
184
|
+
});
|
|
185
|
+
|
|
186
|
+
test('should handle resize events', () => {
|
|
187
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
188
|
+
'https://example.com',
|
|
189
|
+
{},
|
|
190
|
+
);
|
|
191
|
+
component.mount('#parent');
|
|
192
|
+
|
|
193
|
+
const iframe = mockAppendChild.mock.calls[0][0] as HTMLIFrameElement;
|
|
194
|
+
|
|
195
|
+
// Get the resize callback and trigger it directly
|
|
196
|
+
const resizeCallback = callbacks.get(CMType.RESIZE);
|
|
197
|
+
resizeCallback({ type: CMType.RESIZE, height: 500 });
|
|
198
|
+
|
|
199
|
+
expect(iframe.style.height).toBe('500px');
|
|
200
|
+
});
|
|
201
|
+
|
|
202
|
+
test('should handle validation errors', () => {
|
|
203
|
+
const component = new EmbeddedComponent<TestValue, TestOptions>(
|
|
204
|
+
'https://example.com',
|
|
205
|
+
{},
|
|
206
|
+
);
|
|
207
|
+
const mockErrors = [{ field: 'name', message: 'Required' }];
|
|
208
|
+
const mockValue = { name: '' };
|
|
209
|
+
|
|
210
|
+
// Get the validation callback and trigger it directly
|
|
211
|
+
const validationCallback = callbacks.get(CMType.INVALID);
|
|
212
|
+
validationCallback({
|
|
213
|
+
type: CMType.INVALID,
|
|
214
|
+
errors: mockErrors,
|
|
215
|
+
value: mockValue,
|
|
216
|
+
});
|
|
217
|
+
|
|
218
|
+
expect(component.errors).toEqual(mockErrors);
|
|
219
|
+
expect(component.value).toEqual(mockValue);
|
|
220
|
+
});
|
|
221
|
+
});
|
|
222
|
+
});
|
package/src/types.ts
CHANGED
|
@@ -531,6 +531,15 @@ export interface Transaction extends ComponentRequest {
|
|
|
531
531
|
};
|
|
532
532
|
}
|
|
533
533
|
|
|
534
|
+
export interface RefreshSource {
|
|
535
|
+
url: URI;
|
|
536
|
+
key: string;
|
|
537
|
+
}
|
|
538
|
+
|
|
539
|
+
export interface Refreshable {
|
|
540
|
+
refreshSource?: RefreshSource;
|
|
541
|
+
}
|
|
542
|
+
|
|
534
543
|
/**
|
|
535
544
|
* Extended transaction interface for deposits
|
|
536
545
|
* @public
|
|
@@ -543,13 +552,19 @@ export interface DepositTransaction extends Transaction {
|
|
|
543
552
|
* An object representing a withdrawal transaction
|
|
544
553
|
* @public
|
|
545
554
|
*/
|
|
546
|
-
export interface Withdrawal
|
|
555
|
+
export interface Withdrawal
|
|
556
|
+
extends BeneficiaryFields,
|
|
557
|
+
Transaction,
|
|
558
|
+
Refreshable {}
|
|
547
559
|
|
|
548
560
|
/**
|
|
549
561
|
* An object representing a deposit transaction
|
|
550
562
|
* @public
|
|
551
563
|
*/
|
|
552
|
-
export interface Deposit
|
|
564
|
+
export interface Deposit
|
|
565
|
+
extends OriginatorFields,
|
|
566
|
+
DepositTransaction,
|
|
567
|
+
Refreshable {}
|
|
553
568
|
|
|
554
569
|
/**
|
|
555
570
|
* An object representing a request for a deposit
|
|
@@ -1010,6 +1025,7 @@ export enum ProofStatus {
|
|
|
1010
1025
|
* - BIP322: Bitcoin message signature following BIP-322
|
|
1011
1026
|
* - TIP191: Tron message signing
|
|
1012
1027
|
* - ED25519: Ed25519 signature (used in Solana)
|
|
1028
|
+
* - XRP_ED25519: Ed25519 signature (used in XRP)
|
|
1013
1029
|
* - XPUB: Extended public key signature for HD wallets
|
|
1014
1030
|
* - MicroTransfer: Proof via small blockchain transaction
|
|
1015
1031
|
* - Screenshot: Image proof of ownership/access
|
|
@@ -1033,6 +1049,7 @@ export enum ProofTypes {
|
|
|
1033
1049
|
BIP137_XPUB = 'xpub',
|
|
1034
1050
|
TIP191 = 'tip-191',
|
|
1035
1051
|
ED25519 = 'ed25519',
|
|
1052
|
+
XRP_ED25519 = 'xrp-ed25519',
|
|
1036
1053
|
CIP8 = 'cip-8',
|
|
1037
1054
|
MicroTransfer = 'microtransfer',
|
|
1038
1055
|
Screenshot = 'screenshot',
|